Hiding UIStatusBar / Moving UINavigationBar
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 sharedA开发者_StackOverflow中文版pplication].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 window always underlaps the status bar, so you shouldn't try to resize it.
Instead, resize the view of your window's root view controller to [[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];
}
As far as I know if you hide the status bar your views automatically occupy the new space and you don't have to change the window frame manually. What happens if you try just this
if ([UIApplication sharedApplication].statusBarHidden != hideStatusBar)
{
[[UIApplication sharedApplication] setStatusBarHidden:hideStatusBar withAnimation:UIStatusBarAnimationSlide];
}
This is what solved it for me
Just a View:
[self.view setFrame: [self.view bounds]];
A view with a scroll view inside
[self.view setFrame: [self.view bounds]];
[self.theScroller setFrame: [self.view bounds]];
"theScroller is the name of my scrollview
精彩评论