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.