3

I want to do some layout change when the devices rotate. So I implement - (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration method to do the work. But I realize when this method is called the self.view.frame and self.view.bounds are different. The self.view.bounds.size is correct and the self.view.frame.size seems still not rotate.

For example, I created an empty singleView Project and implemented the method like follows:

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    NSLog(@"willAnimateRotationToInterfaceOrientation");

    NSLog(@"self.view.bounds.size width:%f height:%f ",self.view.bounds.size.width,self.view.bounds.size.height);
    NSLog(@"self.view.frame.size width:%f height:%f",self.view.frame.size.width,self.view.frame.size.height);

}

when the device rotates from portrait to landscape. the output is as follows:

2013-06-11 11:57:46.959 viewDemo[95658:707] willAnimateRotationToInterfaceOrientation
2013-06-11 11:57:46.961 viewDemo[95658:707] self.view.bounds.size width:1024.000000 height:748.000000 
2013-06-11 11:57:46.961 viewDemo[95658:707] self.view.frame.size width:748.000000 height:1024.000000

I wonder why these sizes are different? They shouldn't be always the same? And when to choose which one to use?

Any help will be appreciated.

chancyWu
  • 14,073
  • 11
  • 62
  • 81
  • If you look in the docs it states that if the transform is anything other than the identity transform the the frame parameter should not be used. Add logs for the view's transform to see how they look in different rotations. – Abizern Jun 17 '13 at 08:28

4 Answers4

5

Look at the answer by "tc.", which is accepted as of now. Copying few lines from that answer to here.

So, the "frame" is relative to the parent view, which in this case is the UIWindow. When you rotate device, the window doesn't rotate; the view controller's view does. From the window's perspective, everything is effectively in portrait mode. This is why even after device is rotated to landscape, self.view.frame will not change.

You should use self.view.bounds to perform any calculation as it gives you the correct values independent of your device orientation.

Community
  • 1
  • 1
Geek
  • 8,280
  • 17
  • 73
  • 137
  • why the window doesn't rotate? – chancyWu Jun 11 '13 at 06:09
  • @chancy What I guess is only UIView can be rotated. This is how apple has designed SDK that we can't modify anything related to UIWindow. While device is getting rotated, the view's superView(i.e. window) is visible at the corners, which appears to be still and not rotating with view. And, hence, self.view.frame has not changed. – Geek Jun 11 '13 at 06:29
  • you mean self.view.frame will not be changed when device rotates? – chancyWu Jun 11 '13 at 06:41
  • Your answer is reasonable.Thanks a lot. – chancyWu Jun 11 '13 at 06:55
2

I wonder why these values are different? They shouldn't be always the same?
The bounds of an UIView is the rectangle, expressed as a location (x, y) and size (width, height) relative to its own coordinate system (0,0).

The frame of an UIView is the rectangle, expressed as a location (x, y) and size (width, height) relative to the superview it is contained within.

In the case of the bounds, the x and y coordinates are at 0,0 as these coordinates are relative to the view itself. However, the frame x and y coordinates are relative to the position of the view within the parent view

And when to choose which one to use?
Hopefully this helps clarify the circumstances where each property might get used.
UIView's frame, bounds, center, origin, when to use what?

Community
  • 1
  • 1
alloc_iNit
  • 5,173
  • 2
  • 26
  • 54
0

please note that frame.size is not equal to bounds.size when the simulator is rotated

refer to this one UIView frame, bounds and center

Community
  • 1
  • 1
Agent Chocks.
  • 1,312
  • 8
  • 19
0

Just use method did(The size is new) not will(The size is same as was in parent controller)

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];

    [halfView setFrame:CGRectMake(0, 0, self.view.bounds.size.width, 120)];
    NSLog(@"willAnimateRotationToInterfaceOrientation");
    NSLog(@"self.view.bounds.size width:%f height:%f ",self.view.bounds.size.width,self.view.bounds.size.height);
    NSLog(@"self.view.frame.size width:%f height:%f",self.view.frame.size.width,self.view.frame.size.height);

}
dip
  • 129
  • 1
  • 4