1 00:00:00,430 --> 00:00:03,030 Before we resolve any of these layout issues, 2 00:00:03,030 --> 00:00:07,810 we need to understand how our views are sized and positioned in the first place. 3 00:00:07,810 --> 00:00:11,130 So far in the past, we've added constraints to our views, but 4 00:00:11,130 --> 00:00:15,350 never fully looked at how exactly the system knows where to place them. 5 00:00:15,350 --> 00:00:18,820 Let's imagine this is an apple working with a blank canvas so 6 00:00:18,820 --> 00:00:21,850 far that just contains a single base view. 7 00:00:21,850 --> 00:00:25,850 The origin of this view is at the top left at zero zero. 8 00:00:25,850 --> 00:00:28,610 Now, we add a sub view to this view. 9 00:00:28,610 --> 00:00:31,800 How do we understand the layout and size of this view, 10 00:00:31,800 --> 00:00:34,750 the sub view, relative to the rest of the screen? 11 00:00:34,750 --> 00:00:37,860 When we talk about the size and position of a view, 12 00:00:37,860 --> 00:00:42,560 we're typically talking about it in terms of the coordinate space of its super view. 13 00:00:42,560 --> 00:00:45,220 The size and layout of a view 14 00:00:45,220 --> 00:00:49,890 in its super views coordinate space is known as a views frame. 15 00:00:49,890 --> 00:00:52,670 And is defined by a CGRect. 16 00:00:52,670 --> 00:00:54,160 CGRect is a struct. 17 00:00:54,160 --> 00:00:57,180 A c struct mind you, not a swift native struct 18 00:00:57,180 --> 00:01:01,490 that encapsulates information about a view's origin and size. 19 00:01:01,490 --> 00:01:04,260 A view's frame is a rectangle, 20 00:01:04,260 --> 00:01:08,100 the smallest rectangle, that fully encloses a view. 21 00:01:08,100 --> 00:01:09,900 Why do I say a smallest rectangle? 22 00:01:09,900 --> 00:01:11,930 Well, you'll understand in a second. 23 00:01:11,930 --> 00:01:16,180 The origin of a view's frame is the distance from the top left 24 00:01:16,180 --> 00:01:17,960 of the super view's origin. 25 00:01:17,960 --> 00:01:21,236 And the size of the frame is the size of the underlying view. 26 00:01:21,236 --> 00:01:27,236 In this example, the frame of our sub view is 100, 200, 200, 200. 27 00:01:27,236 --> 00:01:30,884 It's important to know that frame is actually not a stored property 28 00:01:30,884 --> 00:01:33,010 on the view but a computed one. 29 00:01:33,010 --> 00:01:35,360 When we learned about computed properties, 30 00:01:35,360 --> 00:01:38,050 we learned that they could have getters and setters. 31 00:01:38,050 --> 00:01:39,830 When you set of view's frame, 32 00:01:39,830 --> 00:01:44,280 it actually changes a couple of their underlying properties of the view. 33 00:01:44,280 --> 00:01:47,180 What properties does changing the frame change? 34 00:01:47,180 --> 00:01:49,680 Well the first is the view center. 35 00:01:49,680 --> 00:01:54,390 Every view has a center property that identifies the center of the view. 36 00:01:54,390 --> 00:01:57,686 But does so in its super view's coordinate space. 37 00:01:57,686 --> 00:02:01,146 In this example, the view center is 200, 300. 38 00:02:01,146 --> 00:02:04,960 So, center defines a view's location in its super view. 39 00:02:04,960 --> 00:02:06,550 Well, what about the size? 40 00:02:06,550 --> 00:02:09,340 This is defined by a view's bounds. 41 00:02:09,340 --> 00:02:14,220 Bounds is also a rect, again a CGRect, with both an origin and size. 42 00:02:14,220 --> 00:02:16,430 The difference between the bounds and 43 00:02:16,430 --> 00:02:21,200 frame is that the bounds is a rect in the view's own coordinate space 44 00:02:21,200 --> 00:02:25,130 where the frame is a rect in the super view's coordinate space. 45 00:02:25,130 --> 00:02:29,510 So bounds defines the size of the view in its own coordinate space. 46 00:02:29,510 --> 00:02:31,950 In this case, our bound size is 200 200, 47 00:02:31,950 --> 00:02:36,370 which for now matches exactly our frame size. 48 00:02:36,370 --> 00:02:41,140 The bounds' origin, which is within the view's own coordinate space is 0,0. 49 00:02:41,140 --> 00:02:44,170 Right now, we're going to just ignore the bounds' origin 50 00:02:44,170 --> 00:02:46,980 because it isn't used in computing the frame. 51 00:02:46,980 --> 00:02:48,170 When computing the frame, 52 00:02:48,170 --> 00:02:51,280 there are several properties that are taken into account. 53 00:02:51,280 --> 00:02:54,890 But when you change a view's frame, it changes a view's center and 54 00:02:54,890 --> 00:02:56,560 bounds property only. 55 00:02:56,560 --> 00:03:00,660 Remember that frame and center are defined in these super view's coordinate space, 56 00:03:00,660 --> 00:03:03,800 while bounds is in the view's own coordinate space. 57 00:03:03,800 --> 00:03:06,680 Now, despite what this example may indicate, bounds and 58 00:03:06,680 --> 00:03:09,160 frame are not always the same thing. 59 00:03:09,160 --> 00:03:13,250 To see how they differ, let's apply a transformation to our view and 60 00:03:13,250 --> 00:03:15,140 scale it down 50%. 61 00:03:15,140 --> 00:03:18,960 When we apply a transformation, we don't actually change the views bounds or 62 00:03:18,960 --> 00:03:22,150 its size but we do change the views frame. 63 00:03:22,150 --> 00:03:27,320 This is because transformation is also used in the computation of a view's frame. 64 00:03:27,320 --> 00:03:30,136 The dotted line represents our old frame. 65 00:03:30,136 --> 00:03:34,810 And the new frame is now 150, 250, 100,100. 66 00:03:34,810 --> 00:03:39,790 So this is a simple case that highlights how the frame differs from the bounds. 67 00:03:39,790 --> 00:03:43,640 While the underlying views, size and therefore bounds is the same, 68 00:03:43,640 --> 00:03:48,100 the frame that displays the actual view inside the coordinate space of its 69 00:03:48,100 --> 00:03:52,840 super view is now 50% smaller around the view's center. 70 00:03:52,840 --> 00:03:56,730 Okay, now what would happen if we applied a rotation to our view? 71 00:03:56,730 --> 00:03:59,606 Let's rotate our view 45 degrees around the center. 72 00:03:59,606 --> 00:04:01,266 Here is what it would look like. 73 00:04:01,266 --> 00:04:06,166 Now, our frame is 59, 59, 282, 282. 74 00:04:06,166 --> 00:04:09,926 While the bounds is still 0, 0, 200, 200. 75 00:04:09,926 --> 00:04:12,610 So what's going on with the frame here? 76 00:04:12,610 --> 00:04:17,350 Remember, we said that the frame is the smallest rectangle that encloses a view. 77 00:04:17,350 --> 00:04:20,520 Because the view is diagonally positioned within the super view, 78 00:04:20,520 --> 00:04:24,460 there isn't a one to one mapping between the frame and bounds right now. 79 00:04:24,460 --> 00:04:27,440 In this case, the bounds is still the original bounds, but 80 00:04:27,440 --> 00:04:29,680 the frame is completely different. 81 00:04:29,680 --> 00:04:33,250 When you position a view on screen, you position it and 82 00:04:33,250 --> 00:04:36,030 size it always within the super view space. 83 00:04:36,030 --> 00:04:37,290 Keep that in mind. 84 00:04:37,290 --> 00:04:41,560 So even though bounds and center really determine the position and size. 85 00:04:41,560 --> 00:04:44,420 We primarily interact with the frame and 86 00:04:44,420 --> 00:04:48,050 then let it determine how to change the underlying properties. 87 00:04:48,050 --> 00:04:51,600 The only time we'll worry about actually manipulating bounds, center, and 88 00:04:51,600 --> 00:04:55,590 transform properties is when we're applying transformations to our view. 89 00:04:55,590 --> 00:04:58,250 So for now all you need to know is that if you want to 90 00:04:58,250 --> 00:05:00,040 change how a view is positioned and 91 00:05:00,040 --> 00:05:04,990 sized on screen, you're going to change the frame of the view because that is how 92 00:05:04,990 --> 00:05:08,440 the view is represented in its super view's coordinate space. 93 00:05:08,440 --> 00:05:10,600 Now that you know about a view's frame, let's try and 94 00:05:10,600 --> 00:05:14,480 manipulate these values ourselves in code to sort out our layout problems.