11
votes

On iOS 7, if I use the prefersStatusBarHidden method and return an instance variable that can be changed:

- (BOOL)prefersStatusBarHidden {
    return self.statusBarShouldBeHidden;
}

And I change the instance variable, thus hiding the status bar, the navigation bar loses the 20pt of height that the status bar occupies. I don't want this, however. Is it possible to hide the status bar but keep the height of the navigation bar?

3
github.com/molon/MMDrawerController/blob/master/… The link will help you. You just need pay attetion to [UINavigationBar+FixFrameAfterHideStatusBar] category.molon

3 Answers

8
votes

I found one solution to this problem at the following blogpost: http://www.factorialcomplexity.com/blog/2014/08/05/fixed-height-navigation-bar-on-ios7.html but his solution uses method swizzling on UINavigationBar, which I find unappealing.

UPDATE:

I figured out that subclassing UINavigationBar and providing a similar implementation to the swizzled solution solves this problem (Swift here, but the same works in Obj-C):

class MyNavigationBar: UINavigationBar {
    override func sizeThatFits(size: CGSize) -> CGSize {
        var size = super.sizeThatFits(size)
        if UIApplication.sharedApplication().statusBarHidden {
            size.height = 64
        }
        return size
    }
}

Then update the class of the Navigation Bar in your storyboard, or use initWithNavigationBarClass:toolbarClass: when constructing your navigation controller to use the new class.

2
votes

The navigation bar is keeping its height, it's just that the navigation bar and status bar don't have any separator between them (and have the same background), so they appear to be one thing, when, in fact, they are two. So what you really want is for the navigation bar to expand to take up the space previously occupied by both the navigation bar and the status bar.

I've done it like this before (heightCon is an IBOutlet to a height constraint on the navigation bar).

-(IBAction)hideStatusBar:(id)sender {
    static BOOL hidden = YES;
    [[UIApplication sharedApplication] setStatusBarHidden:hidden withAnimation:UIStatusBarAnimationSlide];
    self.heightCon.constant = (hidden)? 64 : 44;
    [UIView animateWithDuration:0.35 animations:^{
        [self.navBar layoutIfNeeded];
    }];
    hidden = ! hidden;
}
0
votes

I didn't get @rdelmar solution to work for me with the NSLayoutConstraint but I used his idea to come up with this very simple code.

[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[UIView animateWithDuration:0.35
                      delay:0
                    options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^{
                             self.navigationBar.top = 20;
                 }
                 completion:nil];

The options:UIViewAnimationOptionBeginFromCurrentState is very important here otherwise the animation is jerky because it starts from 0.