0
1
00:00:00,570 --> 00:00:07,350
In the last lesson, we created a bunch of these container views, so that we can layout the containing
1

2
00:00:07,410 --> 00:00:10,540
elements relative to the containers.
2

3
00:00:10,620 --> 00:00:18,410
But the problem is that we haven't given these containers any dimensions or positions of their own.
3

4
00:00:18,540 --> 00:00:26,010
We haven't specified how they themselves are going to be laid out which is why if we add some constraints
4

5
00:00:26,070 --> 00:00:32,220
to the subviews or the things that are inside these containers, well, it's still ambiguous because it
5

6
00:00:32,220 --> 00:00:37,500
doesn't know how to layout these containers. In order to solve this problem,
6

7
00:00:37,530 --> 00:00:45,060
we're going to learn about something called StackViews. And a StackView is exactly the way it sounds.
7

8
00:00:45,180 --> 00:00:51,960
It's a way for us to be able to stack views together, either vertically, for example, in this case, our
8

9
00:00:51,960 --> 00:00:56,070
three views are vertically stacked on top of each other.
9

10
00:00:56,340 --> 00:01:02,640
Or we could also create horizontal stacks such as our two dice views that are horizontally aligned with
10

11
00:01:02,640 --> 00:01:04,050
each other.
11

12
00:01:04,110 --> 00:01:09,840
If we take our Top View and then hold down the command key, and select the Middle View, and the Bottom
12

13
00:01:09,840 --> 00:01:10,340
View,
13

14
00:01:10,540 --> 00:01:12,600
so we have all three selected.
14

15
00:01:12,750 --> 00:01:21,060
We can go ahead and embed them inside a StackView, so you can go to Editor, Embed in, StackView, or we can
15

16
00:01:21,060 --> 00:01:25,710
simply just select this button and embed it into a StackView.
16

17
00:01:25,860 --> 00:01:32,730
Now that they are in a StackView, Xcode knows how to align these three things relative to each other.
17

18
00:01:33,240 --> 00:01:38,850
But we still got some problems because while we know how these three should be placed relative to each
18

19
00:01:38,850 --> 00:01:46,370
other, namely in a sort of horizontal column, we don't actually know where the StackView begins and ends.
19

20
00:01:46,380 --> 00:01:54,360
So in addition to putting these views inside a StackView, we also have to give the StackView some constraints
20

21
00:01:54,540 --> 00:01:57,150
relative to its superview.
21

22
00:01:57,150 --> 00:02:03,930
But this is relatively easy because we want that stack to stretch out so that it takes up the entire
22

23
00:02:03,930 --> 00:02:09,240
screen and to make sure that it doesn't go into the safe areas.
23

24
00:02:09,270 --> 00:02:14,880
Think about what you did for the background in terms of setting its constraint. And as a challenge, I
24

25
00:02:14,880 --> 00:02:21,990
want you to add some constraints to the stack view to make these errors disappear and the stack view
25

26
00:02:22,020 --> 00:02:28,610
should be constrained so that it doesn't go into any of the safe areas at the top or at the bottom.
26

27
00:02:28,740 --> 00:02:32,500
Pause the video and have a think about this problem and try to solve it.
27

28
00:02:34,160 --> 00:02:34,490
All right.
28

29
00:02:34,520 --> 00:02:40,610
So we've got our StockView selected and we're going to add some constraints. Now, in my case, I want it
29

30
00:02:40,610 --> 00:02:49,190
to be zero from all four sides. And instead of being relative to the superview, I want it to be relative
30

31
00:02:49,250 --> 00:02:51,210
to the safe areas.
31

32
00:02:51,230 --> 00:02:58,280
Now, notice how when we click on the dropdown, we can select Safe Area in most of these dropdowns, other
32

33
00:02:58,280 --> 00:02:59,390
than the top one.
33

34
00:02:59,790 --> 00:03:07,430
Well, in my case, the reason is actually because this top part of the StackView has already gone past
34

35
00:03:07,430 --> 00:03:08,550
the safe area.
35

36
00:03:08,630 --> 00:03:12,620
You can see where the safe area is and you can see where my StackView ends.
36

37
00:03:12,620 --> 00:03:19,490
So if we bring it down just a little bit so that it's right next to the safe area, then if I try to add
37

38
00:03:19,490 --> 00:03:26,200
my constraints this time, you can see that the safe area now exists as a possible relationship.
38

39
00:03:26,270 --> 00:03:30,490
So let's go ahead and add these zero to all four sides.
39

40
00:03:30,680 --> 00:03:34,610
But notice how my bottom constraint is no longer showing the safe area.
40

41
00:03:35,030 --> 00:03:40,850
So let's go ahead and simply add this as a zero constraint to the containing view,
41

42
00:03:40,850 --> 00:03:47,080
and then we're going to add these four constraints and we can find unit using our Attribute Inspector.
42

43
00:03:47,150 --> 00:03:52,360
So if I go ahead and select the bottom of my StackView,
43

44
00:03:52,370 --> 00:03:54,980
so it should read Stack View.bottom.
44

45
00:03:54,980 --> 00:04:00,110
You can see that currently, it's set relative to the superview's bottom.
45

46
00:04:00,110 --> 00:04:05,870
So let's go ahead and change that to the Safe Area Bottom and change that constant to a zero.
46

47
00:04:06,260 --> 00:04:12,030
And now if I hit enter, it will be aligned relative to the bottom of the safe area.
47

48
00:04:12,140 --> 00:04:17,050
Now that we've constrained our StackView to all four sides,
48

49
00:04:17,240 --> 00:04:20,680
the next thing to do is to configure the stack.
49

50
00:04:20,690 --> 00:04:26,870
Now, notice when you drop three elements that are roughly vertically on top of each other inside a StackView,
50

51
00:04:26,880 --> 00:04:30,860
it'll automatically choose the vertical axis.
51

52
00:04:30,860 --> 00:04:36,890
Now, the next thing we're going to do is we're going to change the distribution to fill equally because
52

53
00:04:36,890 --> 00:04:43,580
we want all three of these views that are contained in my stack to have equal heights along the vertical
53

54
00:04:43,580 --> 00:04:44,670
axis.
54

55
00:04:44,780 --> 00:04:51,050
And as soon as I do that, you'll notice some more errors will go away, and you'll know how to layout these
55

56
00:04:51,050 --> 00:04:55,160
three elements even if it's in a horizontal orientation.
56

57
00:04:55,160 --> 00:04:58,080
Notice how it's avoiding all of the safe areas.
57

58
00:04:58,100 --> 00:05:04,590
Meanwhile it's dividing the height evenly between all three containers.
58

59
00:05:04,580 --> 00:05:10,900
So now that we've specified our stack, it makes it so much easier to align these other elements.
59

60
00:05:11,300 --> 00:05:18,050
So our Roll button, for example, can now be horizontally and vertically aligned in its container which
60

61
00:05:18,050 --> 00:05:21,600
is, of course, now the bottom view rather than this one.
61

62
00:05:21,620 --> 00:05:23,930
So let's go ahead and add those two constraints.
62

63
00:05:23,930 --> 00:05:25,660
And it gets put in the middle.
63

64
00:05:25,820 --> 00:05:34,610
Now, as a challenge, I want you to put these two dice views in a horizontal container, so that they are
64

65
00:05:34,760 --> 00:05:41,500
equally aligned to each other horizontally. So pause the video and try to complete that challenge.
65

66
00:05:41,960 --> 00:05:42,330
Okay.
66

67
00:05:42,360 --> 00:05:49,890
So as we did before, we select these two things, and then we go ahead and embed them in a StackView
67

68
00:05:50,240 --> 00:05:56,270
and because they're roughly next to each other on the horizontal axis, they automatically get placed
68

69
00:05:56,450 --> 00:05:58,850
in a horizontal StackView.
69

70
00:05:59,450 --> 00:06:07,130
And now we can select our stack and make it centered in the middle container.
70

71
00:06:07,130 --> 00:06:12,590
You can also adjust the spacing between the elements in the stacks.
71

72
00:06:12,590 --> 00:06:19,490
So, for example, our vertical stack, if you wanted to have more spacing, say, let's change it to 30, then
72

73
00:06:19,490 --> 00:06:22,430
you could have these elements spaced further apart.
73

74
00:06:22,430 --> 00:06:27,950
But in our case, I actually want the spacing to be minimal, just enough so we can actually see the edges
74

75
00:06:27,950 --> 00:06:34,310
of each of the containers, but I don't want them to have a lot of distance away from each other, so that
75

76
00:06:34,310 --> 00:06:38,600
when we go into the horizontal, there's enough space to go around.
76

77
00:06:38,690 --> 00:06:45,290
Now, for our horizontal stack, I'm going to change the spacing to about 50 to keep them a little bit closer
77

78
00:06:45,290 --> 00:06:46,340
together.
78

79
00:06:46,460 --> 00:06:52,670
And once you're done with using these containers, because we're only using them for layout, we don't actually
79

80
00:06:52,670 --> 00:07:00,830
want it to look like this in our final app, we can go ahead and select these container views and change
80

81
00:07:00,830 --> 00:07:04,460
the background to default or see through
81

82
00:07:04,850 --> 00:07:12,770
and now, therefore, layouts, but then no longer obscuring our background. Now, the final thing
82

83
00:07:12,830 --> 00:07:20,630
I want to show you is notice how our Roll button has been collapsed, so that it's very small, and fits
83

84
00:07:20,720 --> 00:07:24,200
precisely the size of the text that's inside.
84

85
00:07:24,200 --> 00:07:31,400
And this is because we've added alignment, so center, horizontally, and vertically, in its container,
85

86
00:07:31,400 --> 00:07:35,560
but we haven't specified any sort of size constraints.
86

87
00:07:35,750 --> 00:07:40,940
So by default, it resize itself to fit its contents.
87

88
00:07:40,970 --> 00:07:46,420
So that means that if I had a little bit more text in here, then it will actually make it larger.
88

89
00:07:46,700 --> 00:07:54,020
But if we wanted a little bit of space around the text, then we would actually have to add our own width
89

90
00:07:54,080 --> 00:08:01,700
constraint, so we can specify a custom width and even a custom height if we so wish.
90

91
00:08:01,700 --> 00:08:08,500
So I'm gonna change the width to a hundred and the height to 50, and now I'm gonna add my constraints.
91

92
00:08:08,900 --> 00:08:15,170
But notice that as soon as I added the width constraint, I get a warning here and the warning tells me
92

93
00:08:15,170 --> 00:08:22,280
that there's a problem with Auto Layout because I have a Fixed width constraint.
93

94
00:08:22,520 --> 00:08:28,230
And if we go over here, you can see that it tells us this problem in a little bit more detail.
94

95
00:08:28,490 --> 00:08:34,300
The width is set to always be a hundred, but what if we had more text in there?
95

96
00:08:34,310 --> 00:08:38,960
What if we had a longer piece of text that was being rendered?
96

97
00:08:39,320 --> 00:08:41,800
Well, then it will clip the text,
97

98
00:08:41,810 --> 00:08:42,190
right?
98

99
00:08:42,200 --> 00:08:44,660
It won't show the entire line.
99

100
00:08:44,750 --> 00:08:46,970
So this is what it's trying to warn us about.
100

101
00:08:47,060 --> 00:08:49,170
And there's a couple of ways of fixing this.
101

102
00:08:49,220 --> 00:08:54,800
So if we click on this triangle, you can see we can either remove the constraint which will resize our
102

103
00:08:54,800 --> 00:09:02,600
label to the size of the content or we can set the constraint width being a hundred to being greater
103

104
00:09:02,720 --> 00:09:04,060
than 100.
104

105
00:09:04,070 --> 00:09:11,840
So this allows the label to extend if there's more text or we can set it to greater than the minimum
105

106
00:09:11,840 --> 00:09:12,200
width,
106

107
00:09:12,230 --> 00:09:17,220
so to make sure the button doesn't shrink below the minimum size.
107

108
00:09:17,300 --> 00:09:23,390
So I'm going to select this one and click Confirm.
108

109
00:09:23,390 --> 00:09:30,170
And now it's going to say that it should always be greater or equal to 100.
109

110
00:09:30,380 --> 00:09:37,790
So it means that if I didn't have a lot of text in here, let's return it back to our previous Roll text,
110

111
00:09:38,300 --> 00:09:40,370
then it's going to make it a hundred.
111

112
00:09:40,670 --> 00:09:47,300
But if we had more text in there, then it's going to resize it to fit the text which is exactly what we
112

113
00:09:47,300 --> 00:09:48,280
want.
113

114
00:09:48,290 --> 00:09:55,760
So now we've learned about constraints, namely alignment and pinning constraints , as well as StackViews,
114

115
00:09:55,760 --> 00:10:03,140
vertical, and horizontal stacks, and also these modifiers such as the greater than or equal, or less than
115

116
00:10:03,140 --> 00:10:04,240
or equal.
116

117
00:10:04,280 --> 00:10:11,600
And I think you're ready for a challenge. Head over to the next lesson where we've got a challenge for
117

118
00:10:11,600 --> 00:10:20,090
you to test your understanding of Auto Layout and you're going to apply all of these things to a new
118

119
00:10:20,090 --> 00:10:24,320
app and see how well you've understood what we've talked about.
119

120
00:10:24,400 --> 00:10:25,830
Have fun on the challenge.
120

121
00:10:25,840 --> 00:10:27,050
And I'll see you on the next module.
