tags:

views:

183

answers:

1

A simple iphone program generated by project template View-based Application, with several buttons, and I added following code:

- (void) showInfo: (UIView *) view {
    NSLog(@"view bounds  %6.2f %6.2f %6.2f %6.2f", view.bounds.origin.x, view.bounds.origin.y, view.bounds.size.width, view.bounds.size.height);
    NSLog(@"view frame   %6.2f %6.2f %6.2f %6.2f", view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height);
    NSLog(@"view center  %6.2f %6.2f", view.center.x, view.center.y);
}

- (BOOL)shouldAutorotateToInterfaceOrientation: UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

- (void)willRotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation duration:(NSTimeInterval) duration {
    switch(toInterfaceOrientation) {
        case UIInterfaceOrientationPortrait:
            [self showInfo: self.view];
            break;
        case UIInterfaceOrientationLandscapeLeft:
            [self showInfo: self.view];
            break;
        case UIInterfaceOrientationLandscapeRight:
            [self showInfo: self.view];
            break;
    }
}

- (void) didRotateFromInterfaceOrientation: (UIInterfaceOrientation) fromInterfaceOrientation {
    switch(fromInterfaceOrientation) {
        case UIInterfaceOrientationPortrait:
            [self showInfo: self.view];
            break;
        case UIInterfaceOrientationLandscapeLeft:
            [self showInfo: self.view];
            break;
        case UIInterfaceOrientationLandscapeRight:
            [self showInfo: self.view];
            break;
    }
}

Launch simulator in Portrait, change to landscape right. I can get:

view bounds 0.00 0.00 320.00 460.00
view frame 0.00 20.00 320.00 460.00
view center 160.00 250.00
In portrait, view's size is 320x460, and it's origin is (0,20) because of status bar.

view bounds 0.00 0.00 480.00 300.00
view frame 0.00 0.00 300.00 480.00
view center 150.00 240.00
In landscape right, bounds' size is changed to 480x300, However, the origin of the frame is (0, 0). And the size of frame is different from bounds.

In my head, I imagine that these coordinates are like following pictures:

Portrait

Portrait

My question is: in landscape right, it seems that the frame's origin points to one location while bounds' origin points to a different one. So I think somewhere in a view controller some rotation happens. Where is it and what does it do?

Thanks for reading this long and not-so-clear question. :)

+4  A: 

In landscape mode, the "content view" (controller.view) will be resized and applied a transform of 90 degrees.

Since bounds represent the bounding rectangle in the internal coordinates system, the bounds.origin will always at the upper-left corner of the view itself.

However, frame is the bounding rectangle in the external, or parent, coordinates system. The parent of your view is the window, which still has the origin in the device's absolute upper-left corner. Hence your frame.origin is at that position in landscape mode.

KennyTM
Thanks. Where do resizing and 90-dgree transform happpen? In view controller?
yehnan
@yehnan: In some will-never-be-documented procedures in `UIWindow`.
KennyTM
This was a much better summary of frames vs. bounds than is offered by Apple's own class documentation. I was failing to understand why the height and width of the frame were not with respect to the device's orientation until I read KennyTM's post. (And as a result, I learned that I want to generally stick to laying out subviews in relation to the bounds, as opposed to the frame, of their parent.)
Justin Searls