This is in continuation to the problem I had here(which is still unresolved): link
But this may help understand what is the problem. I created just a simple test project ('Empty Application') and added a view controller with a XIB file (check box: 'With XIB file for user interface' selected). Code looks like this:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"didLoad: %@",NSStringFromCGRect(self.view.bounds));
// Do any additional setup after loading the view from its nib.
}
-(void) viewDidAppear:(BOOL)animated
{
NSLog(@"didAppear: %@",NSStringFromCGRect(self.view.bounds));
}
This is the output:
2013-07-26 17:05:28.502 testtest[5926:c07] didLoad: {{0, 0}, {320, 548}}
2013-07-26 17:05:28.506 testtest[5926:c07] didAppear: {{0, 0}, {320, 460}}
How come they are different?
(ps. I am testing on 6.1 simulator)
When the viewDidLoad
method is called, your view controller has only just been loaded from your storyboard or XIB, and so the view dimensions are equal to those that you have in the XIB (those looks like iPhone 5 height dimensions).
Later, when viewDidAppear:
is called, the view has already appeared on the screen, so it has been resized appropriately to actually fit on the screen, so its dimensions may be different to those in your storyboard, and consequently different to those that are set when the view is loaded.
In your case, it looks like your storyboard or XIB file is set to iPhone 5 screen size (548 = 1136/2 - status bar), and you are testing in a pre-iPhone 5 simulator or device with a 480x320 point screen, so the view gets resized down to 460 points high to fit on the screen.
This could have perfect sense.
ViewDidLoad
is called lazily when first access of controller.view
, so by that time the frame is not set yet. This means that you can not rely on the frame/bounds sizes at this point because it will only contain a default value (although in many cases it will be correct).
In ViewDidAppear
, the frame is usually set, although if your parent controller is setting any animation you could also have a temporal frame state instead of the final one, but it is not usual as by convention this method is called when the view is already displayed.
For example, if you are loading the view from an IB file, the frame you will get in the viewDidLoad
is the one you have in the IB file, but maybe the final size for your view is smaller/bigger, and then you will get another one in your viewDidAppear
.
Instead of that, you should create all your elements resizable (use Spring&Struts, AutoLayout or any other similar alternative) so they will be properly displayed when the frame is set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With