When would a UIView's bounds.origin not be (0, 0)?
View's frame determines its location in superview. View's bounds determines its subviews locations. That means, if you change view's bounds, its location won't be changed, but all of its subviews location will be changed.
Positive width and height is like you draw a view from upper-left to bottom-right, while negative value is from bottom-right to upper-left. So
frame1 = CGRectMake(100, 100, -50, -50)
is totally identical with
frame2 = CGRectMake(50, 50, 50, 50).
And in fact, if you init a view with frame1, it will AUTOMATICALLY CHANGED to frame2.
But the bounds.origin
of the views are not identical. Bounds.origin
indicates the point that you "draw" the view, so all subviews frames will originate at this point.
For example, in Landscape iPhone 6, we have:
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 275, 275)];
leftView.backgroundColor = [UIColor greenColor];
[self.view addSubview:leftView];
UIView *rightView = [[UIView alloc] initWithFrame:CGRectMake(667-50, 375-50, -275, -275)];
rightView.backgroundColor = [UIColor blueColor];
[self.view addSubview:rightView];
And we got:
We will find that rightView's frame is automatically changed to positive value, which is (342, 50, 275, 275), but its bounts.origin = (-275,-275)
.
And we add subviews:
UIView *leftSubview = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
leftSubview.backgroundColor = [UIColor grayColor];
[leftView addSubview:leftSubview];
UIView *rightSubview= [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
rightSubview.backgroundColor = [UIColor grayColor];
[rightView addSubview:rightSubview];
So the bounds makes rightView's subview follows the origin which we init rightView.
If we change the bounds of rightView equals to leftView: rightView.bounds = leftView.bounds; Then the two subViews location is the same, we lost the information that rightView's width and height are negative.
And we change the bounds of leftView instead of rightView: CGRect bounds = leftView.bounds; bounds.origin = CGPointMake(50, 50); leftView.bounds = bounds;
We can see, its subview's frame.origin is offset by bounds.origin(using minus, not plus).
To conclude:
view.bounds
determines all its subview's location(offset by bounds.origin), whilebounds
will not affect its own location in its superview.If you init a view with negative width and height, it will automatically changed to positive(which won't change the location), but its bounds.origin indicates the point that you start to "draw" the view.
A UIScrollView's bounds.origin will not be (0, 0) when its contentOffset is not (0, 0).
The bounds.origin will be negative if you initialize a view with negative width/height. For example, if you did
UIView* v = [[UIView alloc] initWithFrame:CGRectMake(5, 5, -10, -20)];
the frame would be:
origin = {
x = -5,
y = -15
},
size = {
width = 10,
height = 20
}
bounds:
origin = {
x = -10,
y = -20
},
size = {
width = 10,
height = 20
}
center:
x = 0,
y = -5
try it for yourself!