天天看點

UIView frame, bounds and center

URL:http://stackoverflow.com/questions/5361369/uiview-frame-bounds-and-center

First a recap on the question: frame, bounds and center and theirs relationships.

Frame A view's 

frame

 (

CGRect

) is the position of its rectangle in the 

superview

's coordinate system. By default it starts at the top left.

Bounds A view's 

bounds

CGRect

) expresses a view rectangle in its own coordinate system.

Center A 

center

 is a 

CGPoint

 expressed in terms of the 

superview

's coordinate system and it determines the position of the exact center point of the view.

Taken from UIView + position these are the relationships (they don't work in code since they are informal equations) among the previous properties:

  • frame.origin = center - (bounds.size / 2.0)

  • center = frame.origin + (bounds.size / 2.0)

  • frame.size = bounds.size

NOTE: These relationships do not apply if views are rotated. For further info, I will suggest you take a look at the following p_w_picpath taken from The Kitchen Drawer based on Stanford CS193p course. Credits goes to @Rhubarb.

UIView frame, bounds and center

Using the 

frame

 allows you to reposition and/or resize a view within its 

superview

. Usually can be used from a 

superview

, for example, when you create a specific subview. For example:

// view1 will be positioned at x = 30, y = 20 starting the top left corner of [self view]// [self view] could be the view managed by a UIViewControllerUIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];    view1.backgroundColor = [UIColor redColor];[[self view] addSubview:view1];      

When you need the coordinates to drawing inside a 

view

 you usually refer to 

bounds

. A typical example could be to draw within a 

view

 a subview as an inset of the first. Drawing the subview requires to know the 

bounds

 of the superview. For example:

UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 400.0f, 400.0f)];    view1.backgroundColor = [UIColor redColor];UIView* view2 = [[UIView alloc] initWithFrame:CGRectInset(view1.bounds, 20.0f, 20.0f)];    view2.backgroundColor = [UIColor yellowColor];[view1 addSubview:view2];      

Different behaviours happen when you change the 

bounds

 of a view. For example, if you change the 

bounds

size

, the 

frame

 changes (and vice versa). The change happens around the 

center

 of the view. Use the code below and see what happens:

NSLog(@"Old Frame %@", NSStringFromCGRect(view2.frame));NSLog(@"Old Center %@", NSStringFromCGPoint(view2.center));    CGRect frame = view2.bounds;frame.size.height += 20.0f;frame.size.width += 20.0f;view2.bounds = frame;NSLog(@"New Frame %@", NSStringFromCGRect(view2.frame));NSLog(@"New Center %@", NSStringFromCGPoint(view2.center));      

Furthermore, if you change 

bounds

origin

 you change the 

origin

 of its internal coordinate system. By default the 

origin

 is at 

(0.0, 0.0)

 (top left corner). For example, if you change the 

origin

 for 

view1

 you can see (comment the previous code if you want) that now the top left corner for 

view2

 touches the 

view1

 one. The motivation is quite simple. You say to 

view1

 that its top left corner now is at the position 

(20.0, 20.0)

 but since 

view2

's 

frame

origin

 starts from 

(20.0, 20.0)

, they will coincide.

CGRect frame = view1.bounds;frame.origin.x += 20.0f;frame.origin.y += 20.0f;view1.bounds = frame;      

The 

origin

 represents the 

view

's position within its 

superview

 but describes the position of the 

bounds

 center.

Finally, 

bounds

 and 

origin

 are not related concepts. Both allow to derive the 

frame

 of a view (See previous equations).

View1's case study

Here is what happens when using the following snippet.

UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];view1.backgroundColor = [UIColor redColor];[[self view] addSubview:view1];NSLog(@"view1's frame is: %@", NSStringFromCGRect([view1 frame]));NSLog(@"view1's bounds is: %@", NSStringFromCGRect([view1 bounds]));NSLog(@"view1's center is: %@", NSStringFromCGPoint([view1 center]));      

The relative p_w_picpath.

UIView frame, bounds and center

This instead what happens if I change 

[self view]

 bounds like the following.

// previous code here...CGRect rect = [[self view] bounds];rect.origin.x += 30.0f;rect.origin.y += 20.0f;[[self view] setBounds:rect];      
UIView frame, bounds and center

Here you say to 

[self view]

 that its top left corner now is at the position (30.0, 20.0) but since 

view1

's frame origin starts from (30.0, 20.0), they will coincide.

Additional references (to update with other references if you want)

  • UIView Geometry
  • UIView Frames and Bounds

About 

clipsToBounds

 (source Apple doc)

Setting this value to YES causes subviews to be clipped to the bounds of the receiver. If set to NO, subviews whose frames extend beyond the visible bounds of the receiver are not clipped. The default value is NO.

繼續閱讀