1

Tried everything. Just trying to hide it for one view controller.

.plist:

Status bar is initially hidden = NO
View controller-based status bar appearance = YES

view controller:

- (BOOL)prefersStatusBarHidden {
    return YES;
}

//I shouldn't have to do this, the above method should suffice. Doesn't work anyway
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [[UIApplication sharedApplication] setStatusBarHidden:YES];

}

Nothing works. Status bar is still there, staring me in the face, laughing through it's ugliness. What do I need to do???

EDIT: prefersStatusBarHidden does not even get called. This view controller is pushed onto the navigation stack via push segue.

soleil
  • 12,133
  • 33
  • 112
  • 183
  • Shouldn't `Status bar is initially hidden` be set to YES? edit: forgot to read the second sentence. my bad. – Hayden Holligan Dec 02 '15 at 20:05
  • Did you try these suggestions: http://stackoverflow.com/questions/23615647/uiviewcontrollers-prefersstatusbarhidden-not-working? – TheEye Dec 02 '15 at 20:50
  • Not really. I'm not presenting modally. I'm just pushing on to the nav stack. – soleil Dec 02 '15 at 23:10
  • 1
    Is there any other code in your project that might be relevant? I just tried to recreate it. Set same values for the .plist, set prefersStatusBarHidden in VC A to false and true in VC B. I created a simple button segue and it works fine. Might need more info – Hayden Holligan Dec 02 '15 at 23:24
  • 1
    What's your view controller hierarchy? Do you have any containing view controllers that may not be correctly forwarding the status bar status request? – jcaron Dec 02 '15 at 23:35
  • This view controller is pushed onto the navigation stack via push segue. I can hide the navigation bar for this view controller, but I cannot hide the status bar. – soleil Dec 02 '15 at 23:47
  • I have read that "The UINavigationController does not forward on preferredStatusBarStyle calls to its child view controllers." So how does one hide the status bar for one of these child view controllers? – soleil Dec 02 '15 at 23:49
  • Wait. Have you modified the preferredStatusBarStyle at all? – Hayden Holligan Dec 02 '15 at 23:53
  • No, preferredStatusBarStyle is not used anywhere in my code. – soleil Dec 02 '15 at 23:58
  • It might be worth trying to isolate your problem in a new project... I can't replicate the problem and without more information it's a little tricky to figure out – Hayden Holligan Dec 03 '15 at 00:01
  • @jcaron you were correct. See my answer for further details. – soleil Dec 03 '15 at 16:52

2 Answers2

1

In any custom containing view controller, implement childViewControllerForStatusBarHidden, returning the current child view controller that should controller the status bar appearance (in this case, the navigation controller).

This will let the system follow the view controller hierarchy down to the current "top" view controller, and it's that view controller's prefersStatusBarHidden which will be queried.

In your custom containing view controller, if the current "active" child view controller changes, call setNeedsStatusBarAppearanceUpdate to let the system know.

jcaron
  • 17,302
  • 6
  • 32
  • 46
0

The key here was that this was never getting called in the view controller:

- (BOOL)prefersStatusBarHidden {
    return YES;
}

Tracing backward, it was not called in the parent navigation controller either. This is because the nav controller was owned by a root view controller. The root view controller did call this method, but did not pass it on to the nav controller, and thus not to any other child view controllers. So for anyone having the same issue and trying to debug, try to track down the view controller at the "root" of your hierarchy.

So in my case, I post a notification from any view controller (viewWillAppear) that I want to hide the status bar. This notification is then consumed by the root controller:

- (void)hideStatusBar:(NSNotification *)notification {
    self.hideStatusBar = YES;
    [self setNeedsStatusBarAppearanceUpdate];
}

Which forces this method to be called on the root controller:

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

And everything works as expected. The same can be done for showing the status bar again.

soleil
  • 12,133
  • 33
  • 112
  • 183
  • 1
    You should actually implement `childViewControllerForStatusBarHidden` in your root view controller, pointing to the navigation view controller (or other child view controller as appropriate). This way, the system will follow the view controller hierarchy directly. If the child view controller changes, call `setNeedsStatusBarAppearanceUpdate` to let the system know. – jcaron Dec 03 '15 at 17:01