Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setStatusBarHidden:NO after XIB load covers UINavigationBar

When setStatusBarHidden:NO is set before the view loads, the UINavigationBar and other elements appear aligned immediately below the StatusBar as they should. However, when setStatusBarHidden:NO is set after the view loads, the UINavigationBar is partially covered.

The StatusBar must be revealed after loading the said view, but how can this be done without encountering the aforementioned problem?

like image 353
Old McStopher Avatar asked Mar 08 '11 04:03

Old McStopher


2 Answers

I found a hack in a code of mine, though can't remember or find where it came from. The trick is to refresh the navigation bar by hiding and reshowing it:

[self.navigationController setNavigationBarHidden:YES animated:NO];
[self.navigationController setNavigationBarHidden:NO animated:NO];

In my code the function looks like this:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationNone];

    [self.navigationController setNavigationBarHidden:YES animated:NO];
    [self.navigationController setNavigationBarHidden:NO animated:NO];
}

However, BE WARNED, this is a hack, and currently I'm struggling with some bugs that appear to originate from this code (navigation item doesn't match navigation content). But since it did work for me in some places, I'd thought I'd mention it.

Edit: I think I found the initial post here: How do I get the navigation bar in a UINavigationController to update its position when the status bar is hidden?

GL, Oded

like image 165
Oded Ben Dov Avatar answered Nov 05 '22 20:11

Oded Ben Dov


(I realise this was an old question, but I just spent half an hour trying to find the answer myself without success, so I thought I would post it here for anyone else who get stuck... especially if you are trying to SHOW the status bar and your view is ending up overlapping it)

I found this works if you want to HIDE the status bar...

[[UIApplication sharedApplication] setStatusBarHidden:YES];
[self.view setFrame: [[UIScreen mainScreen] bounds]];

but not when you want to SHOW the status bar... in that case I use this solution which works, but worries me because it hard codes the status bar height to 20... it also worries me that I have to adjust the view differently depending on orientation. but if I didn't do that it always had the 20 point gap on the wrong edge. In my case I want to turn the status bar off for some views, and then back on when I return. I had particular problems if I rotated the device while the bar was off. so the switch statement, although ugly (someone might post a cleaner solution), works.

[[UIApplication sharedApplication] setStatusBarHidden:NO];

CGRect frame = [[UIScreen mainScreen] bounds];

switch (self.interfaceOrientation) 
{
    case UIInterfaceOrientationPortrait:
        frame.origin.y = 20;
        frame.size.height -= 20;
        break;

    case UIInterfaceOrientationPortraitUpsideDown:
        frame.origin.y = 0;
        frame.size.height -= 20;
        break;

    case UIInterfaceOrientationLandscapeLeft:
        frame.origin.x = 20;
        frame.size.width -= 20;
        break;

    case UIInterfaceOrientationLandscapeRight:
        frame.origin.x = 0;
        frame.size.width -= 20;
        break;

} 

[self.view setFrame:frame];
like image 39
Paul Avatar answered Nov 05 '22 21:11

Paul