I having problems getting an accurate reading for heights and widths. So I made this quick and dirty app to test the situation.
Here is the code:
@interface wwfpViewController ()
@property (nonatomic, strong) UIView * box;
@property (nonatomic, strong) UILabel * info;
@end
@implementation wwfpViewController
@synthesize box,info;
- (void)viewDidLoad {
[super viewDidLoad];
box=[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
[box setBackgroundColor:[UIColor darkGrayColor]];
[box setAutoresizesSubviews:YES];
[box setAutoresizingMask:UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth];
info=[[UILabel alloc] initWithFrame:CGRectMake(10, 10, 300, 300)];
[info setTextColor:[UIColor whiteColor]];
[info setBackgroundColor:[UIColor blackColor]];
[info setLineBreakMode:NSLineBreakByWordWrapping];
[info setNumberOfLines:10];
[info setText:@"..."];
[self.view addSubview:box];
[box addSubview:info];
[self updateInfo];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(updateView:)
name:UIApplicationDidChangeStatusBarOrientationNotification
object:nil];
}
- (void) updateInfo {
CGFloat selfHeight=self.view.frame.size.height;
CGFloat selfWidth=self.view.frame.size.width;
CGFloat boxHeight=box.frame.size.height;
CGFloat boxWidth=box.frame.size.width;
int deviceOrientation=[[UIDevice currentDevice] orientation];
int statusOrientation=[[UIApplication sharedApplication] statusBarOrientation];
NSString * str=[NSString stringWithFormat:@"[height x width] \nself: [%f x %f] \nbox: [%f x %f] \ndevice: %d status: %d",selfHeight,selfWidth,boxHeight,boxWidth,deviceOrientation,statusOrientation];
[info setText:str];
}
- (void) updateView: (NSNotification*) notify {
[self updateInfo];
}
@end
When I test this on an iPad, initially in portrait mode, the info label reports the following:
[height x width]
self: [1004.000000 x 768.000000]
box: [1004.000000 x 768.000000]
device: 0 status: 1
This is correct!
And then when I rotate the iPad to landscape, I get these readings:
[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3
Actual height x width: 748 x 1024
But when I test this on the iPad when its in landscape orientation, the info label reports:
[height x width]
self: [1024.000000 x 748.000000]
box: [1024.000000 x 748.000000]
device: 0 status: 3
Actual height x width: 748 x 1024
Then when I rotate the iPad to portrait, I get these readings:
[height x width]
self: [748.000000 x 1024.000000]
box: [748.000000 x 1024.000000]
device: 1 status: 1
Actual height x width: 1004 x 768
I rotate it back to landscape and then I get these readings:
[height x width]
self: [768.000000 x 1004.000000]
box: [1004.000000 x 768.000000]
device: 3 status: 3
Actual height x width: 748 x 1024
In all cases the box
UIView covers the entire screen, so it is auto adjusting to the orientation changes correctly. These results are consistent from the simulator and testing it on an actual iPad, and I have similar experiences on an iPhone.
After this, I have a few questions:
self.view
different from the height and width for box
when the two look visually identical?[UIDevice ... orientation]
reports as zero the first time it is used, should I just ignore it altogether and just stick with [UIApplication ... statusBarOrientation]
?Check the bounds of the views rather than the frame:
CGFloat selfHeight=self.view.bounds.size.height;
CGFloat selfWidth=self.view.bounds.size.width;
CGFloat boxHeight=box.bounds.size.height;
CGFloat boxWidth=box.bounds.size.width;
Also, I would use the UIViewController
method for orientation changes and remove the NSNotificationCenter
observer.
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
[self updateInfo];
}
Finally, the first call to get the correct size should be in viewWillAppear
as it will be incorrect in viewDidLoad
:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self updateInfo];
}