6

In ViewController.m, on an iPad, if we print out the view's frame height in a tap event handler:

NSLog(@"Height of main view is %f", self.view.frame.size.height);

then in Portrait mode, the value is 1004 (20 pixel for device status line, so 1024 - 20 = 1004), and if the device is rotated to Landscape mode, I expected it to be about 768 or 748, but the value printed is actually 1024. (update: if the app is started in Landscape mode, then without rotation, it is also printed as 1024). Why would that be, and is there a rule of thumb to expect getting the value of 748 or 768? (Is there more than one way to get that?)

Jeremy L
  • 3,770
  • 6
  • 41
  • 62
  • Just to be sure, is your [`autoresizingMask`](http://developer.apple.com/library/ios/#documentation/uikit/reference/uiview_class/uiview/uiview.html#//apple_ref/occ/instp/UIView/autoresizingMask) property correctly set with flag `UIViewAutoresizingFlexibleHeight` ? – psycho May 23 '12 at 10:10
  • I used `UIWindow *window = [[[UIApplication sharedApplication] delegate] window]; window.autoresizingMask |= UIViewAutoresizingFlexibleHeight; self.view.autoresizingMask |= UIViewAutoresizingFlexibleHeight;` in the `viewDidLoad` method and compiled and rotated a few times and the height still came out as 1024 – Jeremy L May 23 '12 at 14:25
  • Hmm.. If you attach a label or something in your view, at the very bottom of the view in portrait mode, is it still viewable in landscape mode? (If yes, no more idea :/) – psycho May 23 '12 at 15:08

3 Answers3

4

In Apple's documents, about UIView's frame:

Warning: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.

So you should use bounds property.

xzgyb
  • 452
  • 2
  • 7
  • since a view might be initialized by `initWithFrame`, if we ignore the `frame` property, it might be weird as it was set with something to begin with – Jeremy L May 23 '12 at 05:51
  • When a view is initialised its transform is the identity transform, so there is no problem here. Have you tried using bounds instead of frame? – jrturton May 23 '12 at 06:33
  • yes, bounds work... if the app is started when the device is in Landscape mode, then is the view still initialized with identity transform? Because even without any further rotation, the height is still 1024 – Jeremy L May 23 '12 at 07:29
1

You can manage the orientation programmatically instead and overwrite the willRotateToInterfaceOrientation method. See the way:

#define IPAD_SIZE_PORTRAIT          CGSizeMake(768, 960)
#define IPAD_SIZE_LANDSCAPE         CGSizeMake(1024, 704)

-(void)relayoutSubviews:(UIInterfaceOrientation)orientation
{
CGSize  scrSize;

if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight))
{
    scrSize = IPAD_SIZE_LANDSCAPE;
}
else
{
    scrSize = IPAD_SIZE_PORTRAIT;
}

self.view.bounds = CGRectMake(0, 0, scrSize.width, scrSize.height);
self.view.frame = CGRectMake(0, 0, scrSize.width, scrSize.height);
}

-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[self relayoutSubviews:toInterfaceOrientation];
}
kallol
  • 319
  • 1
  • 13
0

The reasoning behind this is that when you rotate the device, the view's frame changes to accommodate for the status bar, but does not actually rotate the frame of the view. The device just renders the view in a rotated state, while the view is actually not-rotated. I believe subviews are affected by this change, but the overall view is not.

Glenn Smith
  • 912
  • 1
  • 17
  • 37