This workshop will be retired on May 31, 2020.
Nested Stack Views: Interface Builder10:26 with Pasan Premaratne
In this recipe we're going to recreate a simple social media profile page in Interface Builder using a nested stack view set up containing several views
In this recipe, we're going to implement a very simple version of a social 0:00 media profile page to show you how we can go from simple stack views 0:04 to building something fairly complex. 0:09 So over here I'm copying a portion of Instagram's current profile page 0:12 to arrive at a layout that looks like this. 0:17 So here we have, basically I started out with an empty storyboard scene. 0:19 But because there's a bunch of stuff in here, rather than setting it up yourself, 0:23 just grab the starter project using the link in the notes area. 0:27 Okay, so here I'm copying a portion of Instagram's current profile page. 0:31 Up at the top left, we have a profile picture. 0:36 To the right of that we have the number of posts the user has posted, 0:40 the follower count, and the number of users this user is following. 0:43 Below all of this we have an edit profile and a button to view the settings. 0:48 And then below all of that is a hypothetical tab bar 0:53 with four buttons to view the user's posts. 0:57 So in a grid view, list view, things you tagged, or 0:59 rather things you've been tagged in, and posts that you have saved. 1:03 Now, we're going to try and 1:07 achieve this entire layout using just a series of nested stack views. 1:08 Were we to try this without stack views, we would end up with a lot of constraints. 1:13 So as you'll see with stack views, we'll just have to add just a few. 1:18 Okay, let's start with the post follower and following counts. 1:21 So each of these is a two label pair with a text describing 1:27 the numerical value underneath it, right? 1:31 So 352 and posts, that is a single pair. 1:35 To lay this one out to size and position it, 1:38 we can use a single stack view for each number and description pair. 1:41 So we're gonna select the 352 and the post label, so 1:46 hold down the shift to select both. 1:49 And then embed it in a stack view. 1:52 This should automatically insert it in a vertical stack view. 1:55 Select the stack view from the document outline, and 1:58 then change the alignment to center, 2:02 the distribution change it to fill proportionally, don’t' leave it on fill, 2:07 and then give it a spacing value of four points, easy enough. 2:11 Let's repeat this process for the second pair. 2:16 So we're gonna select 100 and followers, and then embedded a vertical stack view, 2:19 select that stack view, change the alignment to center, 2:26 then distribution to fill proportionally, and give it a spacing of 4 points. 2:30 We'll do this one more time for the last pair. 2:35 It's important here to set these properties to the right values, so 2:38 let me do this real quick before I mess up. 2:43 So we'll embed that, center, fill proportionally, 1, 2, 3, 4. 2:46 Now it's important to set these to the right values. 2:53 For example, if we set distribution to fill equally, for 2:56 example, the stack view will attempt to resize these smaller description 2:59 labels to match the height of the larger count label. 3:04 Since the content hugging priority values across both labels are the same, for 3:08 each stack view in this arrangement we would have to lower the content 3:12 hugging priority on the description label to allow the stack view to resize it. 3:17 Otherwise we would end up with an ambiguous layout. 3:22 So by proportionally filling it out, we avoid that issue. 3:25 Remember that with stacked views we have to position and 3:29 size the stack view itself using auto layout. 3:31 And until we do that, these inner elements won't really be positioned, but 3:35 we'll get to that at the end. 3:39 In all layout, all of these count and 3:40 description labels are displayed in a single row. 3:43 So our next step is to select the three stack views we just created and 3:46 embed them in a horizontal stack view. 3:51 Okay, so now we have a single horizontal stack. 3:55 At this point we have a nested stack view, 3:59 but there is nothing inherently special about this. 4:00 The horizontal stack view just treats each inner stack view as a regular view. 4:03 So select this horizontal stack view we created, and change the distribution to 4:09 equal centering with a space of 8 points between each arranged subview. 4:14 So far so good. 4:21 The next thing we're going to tackle are the buttons below these count labels. 4:23 So select the Edit Profile and Settings button, and embed it in a horizontal stack 4:27 view, and give the resulting stack view a distribution of Fill Proportionally. 4:32 For the spacing value, we're going to click on the drop down and 4:38 select standard spacing. 4:42 Now, we're going to select this horizontal stack view that contains the count and 4:44 description labels, and 4:49 the horizontal stack view containing the edit profile and settings buttons. 4:51 And we're going to embed these in a vertical stack view. 4:56 At this point, we're three levels of nesting deep. 5:01 For this vertical stack view, we're going to give it a standard spacing value and 5:04 just leave it at that. 5:09 Okay, time for another stack view. 5:11 So we're gonna select this resulting stack view we just created, 5:12 along with the profile image view, and embed it in a horizontal stack view. 5:16 Okay, click. 5:22 We'll tweak the spacing on this in just a bit. 5:24 Okay, next up is the horizontal stack view with the row of buttons below. 5:27 So this is going to be easy, 5:32 we'll just drag to select all and then embed it in a horizantal stack view. 5:34 Finally we're going to select both of these stack views and 5:41 embed it in one final vertical stack view. 5:44 Okay, I think we're done, and now we have one single outer stack. 5:48 We can now position this outer stack view and give it a partial size. 5:52 Select the stack view, and then from the Pin menu give it a leading 5:56 top and trailing space constraint with a constant value of 8 points. 6:03 Now, I said partial size earlier because by pinning it on these three, 6:12 on the top, trailing, and leading, and leaving the bottom edge unpinned, 6:17 the stack view can grow vertically to accommodate its subviews. 6:20 If we add more views vertically, it won't break the layout. 6:25 Okay, so we're done with our nested stack views. 6:29 But clearly the layout is not complete. 6:31 Let's fix this. 6:33 So on the outermost stack view, 6:35 this one's selected right now, the alignment is set to Leading. 6:37 Let's change this to Fill. 6:40 Since alignment is perpendicular to the axis, 6:43 this means the views are going to stretch out horizontally, which is what we want, 6:46 We'll also give this outer stack view a spacing of 16 points. 6:50 Let's move down one level. 6:56 And from the drop down, 7:00 select the stack view that encompasses the row of buttons at the bottom. 7:00 Right now, the first button is stretched out, 7:07 while the remaining are sized to their intrinsic content sizes. 7:09 This is because when trying to satisfy layouts, auto layout will prioritize 7:13 the stack views in the order of the arranged sub views. 7:17 We want these buttons to take up an equal amount of space, so 7:21 we're going to change the distribution to fill equally. 7:24 Okay, we're done with that. 7:29 Next, we want to tackle the top horizontal stack view. 7:30 So here we're going to make sure that the distribution and alignment are both 7:34 fill so that in both axis the views take up the entire space, and 7:39 now I'll give them a spacing value of 32 points. 7:43 If we take a step back, our layout looks like our desired end result. 7:48 If you were to run the app however, you'd run into an issue. 7:52 To lower the storyboard found in the simulator, 7:56 you can go over to the project settings, and under the main interface section 7:59 change it to the nested stack view story board found instead of main. 8:04 When you run the app you'll see that despite what you see here in 8:08 the storyboard scene, the layout in the actual app is broken. 8:11 And this because of the image view in our layout. 8:15 An image view is a view with an intrinsic content size. 8:18 Which the stack view relies on to size both it and the views around it. 8:22 Not everything in the scene, other than the image view, 8:27 has an intrinsic content size. 8:29 But since the image view doesn't have an image, it doesn't have a content size. 8:31 And so we run into issues. 8:36 The stack view, once this loads, once this runs in an app, it doesn't know what 8:38 this size is, so it doesn't know what the rest of them should be sized to. 8:42 Now, that begs the question, why does this look okay here, and 8:46 why are there no issues? 8:50 Now, a storyboard scene is this weird in between thing where you can drag and 8:52 drop here, and it has x and y coordinates, and a width and a height. 8:56 But then it also relies on the auto layout constraints to actually set those things. 9:00 So here we've given it a height and a width of 100. 9:05 So as far a the storyboard scene is concerned, this has a size. 9:08 But when you run it, these sizes aren't taken into account because we don't have 9:14 constraints defining those sizes. 9:18 Now there are two ways to fix this. 9:19 One is to add an image to the image view so 9:22 that we have a intrinsic content size, but that's not always gonna work out. 9:24 If the image is too large or too small, 9:29 that'll affect our layout in unpredictable ways. 9:31 The second way is to add an explicit height and 9:34 width constraint on the image view, which is what we're going to do. 9:37 So that's selected, we're going to click on the pin menu and just add a height and 9:40 width constraint. 9:44 And now nothing will change in the storyboard scene, but 9:47 when you run the app our layout should be fine. 9:50 This recipe highlights the power of stack views to build a layout with 9:53 more than just a few views. 9:58 So, in all, to achieve this layout, we have 1, 2, 3, 4, 5, 6, 10:00 7, 8, 9, 10, 11, 12, 13. 10:05 We have 13 views. 10:07 And all we had to do was add a total of 5 constraints. 10:09 By embedding in stack views and 10:13 tweaking a few properties, we were able to arrive at the final layout. 10:15 If you're interested in building this recipe in code, 10:20 check the notes section for a link to the relevant video. 10:23
You need to sign up for Treehouse in order to download course files.Sign up