39

When would an UIView's bounds.origin not be (0, 0)?

This paragraph was helpful to me:

IMPORTANT!! Bounds X and Y, the origin, are for moving inside the View. For eample X+5, moving 5pix to the left of the frame's origin meaning draw all content within this View to the left 5pix of frame's origin. It doesn't do anything to itself, it is what being drew on it that get affected.

But it describes only the case when I had set the value of bounds.origin myself.
In what other cases the value of bounds.origin != (0, 0)?

Blazej SLEBODA
  • 8,936
  • 7
  • 53
  • 93
BergP
  • 3,453
  • 4
  • 33
  • 58

4 Answers4

42

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:

enter image description here

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];

enter image description here

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.

enter image description here

And we change the bounds of leftView instead of rightView: CGRect bounds = leftView.bounds; bounds.origin = CGPointMake(50, 50); leftView.bounds = bounds;

enter image description here

We can see, its subview's frame.origin is offset by bounds.origin(using minus, not plus).

To conclude:

  1. view.bounds determines all its subview's location(offset by bounds.origin), while bounds will not affect its own location in its superview.

  2. 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.

Franz Wang
  • 596
  • 4
  • 14
  • 1
    Great answer. "bounds" is confusing because it gives the impression that the x,y is the position of the view for which its set. Why have they tied the dimensions of a view to its local origin? – Ian Warburton Aug 02 '17 at 14:58
  • Nice answer, thank you for taking the extra time for explaining things alongwith pictorial representations. +1. – Ashish Nov 07 '17 at 15:24
31

A UIScrollView's bounds.origin will not be (0, 0) when its contentOffset is not (0, 0).

Cosyn
  • 4,404
  • 1
  • 33
  • 26
17

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!

ian
  • 1,612
  • 1
  • 12
  • 5
  • That makes no sense. It equals to expression "Origin of coordinate system relative to itself not equal to <0,0>" which is false and makes no sense. – folex Jan 11 '13 at 13:38
  • 1
    Why would you ever want to create a negative width and height? – Boon Nov 06 '13 at 14:40
  • 2
    Making sense or not, those are the results you get if you execute this code. – Ricardo Sanchez-Saez Dec 09 '14 at 18:22
  • Negative width and height is subtracted from the x, y coordinates. Instead of the system blocking or denying negative lengths, it just adjust itself. This is what I understood from this at least – Gustavo Baiocchi Costa Jan 06 '17 at 12:22
0

(edited again because I can’t delete my original answer after it was accepted—credit for this goes to ian, who posted a more thorough answer below:)

In most cases this won’t happen. If you initialize your view with a negative width and/or height, you’ll get an origin with a negative X of the width and/or negative Y of the height.

Noah Witherspoon
  • 57,021
  • 16
  • 130
  • 131
  • 2
    I do not think this is true. I have seen cases where something in the system related to autoresizing seemed to leave me with a bounds where the origin was not 0.0. In my own code I never, ever set bounds so having it suddenly present a non-zero number was a shock. – Kendall Helmstetter Gelner Dec 10 '12 at 06:35
  • @KendallHelmstetterGelner Agreed. This happened to me when I had a navigation controller doing some resizing of my UIScrollView (I think as a result of the "Adjust Scroll View Insets" setting). – eremzeit Jun 04 '14 at 23:45