This workshop will be retired on May 31, 2020.
Complex Width Views: Interface Builder8:04 with Pasan Premaratne
In this recipe we're going to build a two view layout where each view occupies a varying width depending on the available space.
In this recipe, we're going to build a two view layout 0:00 where each view occupies a varying width depending on the available space. 0:03 We'll have two views, a red and a blue view, 0:09 where we want the red view to be double the width of the blue view if possible. 0:12 The catch is that the blue view can't be too narrow either and 0:17 we want to enforce a minimum width. 0:21 We'll need to use a combination of inequality relations and 0:24 constraint priorities to build this recipes. 0:28 You can go ahead and start a new single view application template. 0:31 All we need is an MT storyboard scene. 0:35 I've added an empty storyboard scene here to my existing project. 0:37 Let's drag two views out over here. 0:42 Let me filter from the object library. 0:46 And we'll set this one on the left and we'll give it a background color of blue. 0:51 So the blue view is on the left. 0:59 And then we'll add a red view on the right. 1:01 We won't be doing anything special in the vertical axis. 1:07 So let's get some basic constraints in place. 1:10 We'll set vertical spacing constraints of eight points on the top and bottom for 1:13 both views. 1:17 Lets draw these out. 1:19 All right, so in the pin menu, we'll select 8 on the top and 8 on the bottom. 1:22 I'm going to unselect Constrain to margins. 1:27 Okay and we'll do that for the red view as well. 1:30 So it's 8 on the top and 8 on the bottom. 1:34 In the horizontal axis, regardless of the width of the views, 1:41 we're going to space them eight points out on either side. 1:45 So let's add those constraints in. 1:49 Again, the pin menu is the easiest way to do this. 1:51 So with blue view selected, it's going to be 8 points on the left side. 1:54 So add a leading space constraint of 8 points. 1:59 And then another one on the trailing edge as well. 2:02 And then we'll select the red view and 2:06 we'll give it an 8 point trailing space constraint here too, okay? 2:09 Next, let's set a width constraint on the blue view. 2:15 Remember we said that while we want the blue view to adjust its size 2:19 to accommodate this growing red view, we don't want it to get too narrow. 2:23 So we'll enforce a minimum width by setting a greater than or 2:28 equal constraint. 2:32 So select the blue view. 2:33 And from the pin menu, we'll give it a width constraint of 150 points. 2:35 When you do that, 2:43 now that it has a fixed width, that should resolve the entire layout. 2:44 But we're not done here. 2:48 Next in the size inspector, we're going to find the width constraint we just added. 2:50 So right here and we'll click on Edit. 2:55 Here we'll specify that the type of the relation is greater than or equal. 2:58 Now this quick menu here uses greater and lesser than symbols, so 3:04 if that's confusing, I mean it's very tiny here and it's hard to read. 3:07 So if it's confusing you can just double click on here and 3:11 then under Relation you can select Greater Than or Equal. 3:14 Now when we do this ,the layout goes from being resolved to being incomplete, again. 3:19 That's because by changing the width constraint on the blue view from 3:24 equal to greater than or equal, we don't give it an upper bound. 3:27 Hypothetically, it could now take up nearly all of the available space, 3:32 giving the red view a one point width and the layout would be satisfied. 3:35 It can also fit a wide range of widths between where we're at now and 3:40 that one point wide red view. 3:44 So we have insufficient information here. 3:47 To fix this, we need to define some constraints that allows auto layout 3:50 to determine a width for the red view. 3:55 With a width for the red view, we can then figure out what the resulting width 3:58 of the blue view needs to be, depending on the space it has available. 4:03 So in this recipe, 4:07 we want the red view to be twice as wide as the blue view if possible. 4:08 And I say if possible because we can only do that up to a certain limit. 4:13 In the portrait orientation, 4:18 with the minimum with constraint enforced on the blue view of 150 points. 4:20 There's not enough room to accommodate a red view that's twice as wide. 4:26 But that's okay. 4:30 In that case, we just want the red view to fill up all the remaining space. 4:31 But if there is available space to go up to thrice as wide, 4:36 then we want it to do so. 4:39 This seems complicated but it can be achieved with just one constraint. 4:42 So we're to Ctrl+drag from the red view to the blue view and 4:46 we'll select an Equal Width constraint. 4:50 We don't actually want an equal width constraint here, 4:53 we want a proportional width constraint. 4:56 So let's go down, find that Equal Width constraint and double click to inspect 4:58 the constraint attributes and here, we'll set them the Multiplier value to 2. 5:03 This is going to break the layout yet 5:08 again, because now we're violating the minimum width constraint on the blue view. 5:10 The last adjustment we need to make therefore, 5:16 is to drop the priority on this constraint. 5:19 So right in this view here, we'll drop the Priority level to 750 or high. 5:21 Once we do that, the layout is now resolved. 5:27 By lowering the priority on the proportional width constraint, 5:31 we've effectively made it act like a less than or equal to constraint. 5:35 Since the greater than or equal constraint has a higher priority, on a layout we'll 5:40 first make sure that a minimum width of 150 points on the blue view is forced. 5:44 Having a lower priority than 1000, 5:51 the proportional width constraint is treated as optional. 5:53 Which means that along with the horizontal spacing constraints on 5:57 either side of the red view, 6:00 auto layout will set the red view's width as the remaining available space. 6:02 This means that technically, the red view can be any width 6:07 less then double the blue view's width and at most twice the blue view's width. 6:10 Which is essentially what a less than or equal relation would define. 6:15 It is important to note however, that while it might seem that way, 6:20 all the way auto layout does not view it as a less than or equal relationship. 6:23 You won't be able to add that here and get the same effect. 6:27 If you are to modify the proportional width constraint to have a less than or 6:30 equal relation and a priority of 1,000, the layout will not be satisfied. 6:34 The key here is that the lower priority value on that 6:39 proportional width constraint, allows auto layout to ignore the constraint all 6:43 together when it cannot accommodate it. 6:47 If you select the View as section on the bottom and 6:50 switch to landscape, we'll see how this constraints adapt. 6:54 In this view, we see that the red view is double the width of the blue view. 6:58 But what's interesting is that the blue view is wider as well. 7:03 Since the blue view has a greater than or 7:07 equal constraint, in this orientation there's enough room for 7:09 it to grow after it's own minimum width constraint has been satisfied. 7:13 Effectively, what this allows auto layout to do is to take the available space 7:19 after the horizontal spaces between the views have been deducted and then 7:24 allocate two-thirds of that space to the red view and one-third to the blue view. 7:28 When it does this, it allows the red view to be double the width of the blue view. 7:33 And then since after doing this there's more than 150 points of space available, 7:37 the blue view can grow to fit this space, 7:43 since its width is defined using a greater than or equal constraint. 7:45 So here we have a complex width scenario, 7:50 that was achieved with basically two horizontal constraints. 7:53 If you're interested in learning how to do this in code, 7:58 check the link in the Notes section. 8:01
You need to sign up for Treehouse in order to download course files.Sign up