I have a navigation-based application where it is possible for the user to hide the status bar. This is remembered in a defaults setting.
It is mostly working, with the one exception that if the app is loaded (from scratch, not returned to after going back to the home screen) when the status bar should be visible, when it is toggled to invisible, the navigation bar does not move up to fill the screen. Toggling the setting after that moves the navigation bar up and down correctly, but still with the extra status bar-sized gap between the navigation bar and the top of the screen, or the status bar. If I return to the home screen and re-enter the application, this corrects itself. I therefore assume there is some method being called on the uinavigationcontroller upon return to the application that I need to call after my toggling of the status bar?
I have tried (I think) all combinations of the wantsfullscreenlayout property, I was setting it in the method below but it made no difference, so I ended up setting it (on the navigationcontroller) to NO in the nib.
Here is the code which toggles the status bar. This is in my application delegate, which has the navigationcontroller and window set up as outlets as per the template application.
if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)
{
[[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.25 animations:^{
window.frame = [[UIScreen mainScreen] applicationFrame];
}];
}
else
{
window.frame = [[UIScreen mainScreen] applicationFrame];
}
Thanks for your help.
UPDATE
It seems, via NSLogging, that the problem lies in the frame of the UINavigationBar. So I have added the following code, which works and animates but I am not happy with! I don't feel this can be the "correct" way to do this. In most cases the extra code does nothing since the frame is already at (0,0), but in the one situation where it is incorrect, this gives the right result.
[navigationController.view setNeedsLayout];
CGRect navBarFrame;
UINavigationBar *navBar = nil;
for (UIView *subView in navigationController.view.subviews)
{
if ([subView isMemberOfClass:[UINavigationBar class]])
{
navBar = (UINavigationBar *)subView;
navBarFrame = navBar.frame;
navBarFrame.origin = CGPointMake(0,0);
break;
}
}
if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)
{
[[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.25 animations:^{
window.frame = [[UIScreen mainScreen] applicationFrame];
navBar.frame = navBarFrame;
}];
}
else
{
window.frame = [[UIScreen mainScreen] applicationFrame];
}
the problem lies in the frame of the UINavigationBar. So I have added the following code, which works and animates but I am not happy with! I don't feel this can be the "correct" way to do this. In most cases the extra code does nothing since the frame is already at (0,0), but in the one situation where it is incorrect, this gives the right result.
[navigationController.view setNeedsLayout];
CGRect navBarFrame;
UINavigationBar *navBar = nil;
for (UIView *subView in navigationController.view.subviews)
{
if ([subView isMemberOfClass:[UINavigationBar class]])
{
navBar = (UINavigationBar *)subView;
navBarFrame = navBar.frame;
navBarFrame.origin = CGPointMake(0,0);
break;
}
}
if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)
{
[[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.25 animations:^{
window.frame = [[UIScreen mainScreen] applicationFrame];
navBar.frame = navBarFrame;
}];
}
else
{
window.frame = [[UIScreen mainScreen] applicationFrame];
}