Search code examples
ioscocoa-touchuiviewcontrolleruikitstatusbar

Interactive View Controller dismissal and changing statusBarStyle not compatible?


I'm presenting a modal UINavigationController with an interactive dismiss transition. The parent view controller has a dark status bar and the modal view controller a light status bar. I'm using the iOS 7 view controller-based status bar appearance configuration.

All works fine as long as I present and dismiss the view controller non-interactively. However, when I start an interactive dismiss transition and cancel it, the status bar color remains dark.

I created a sample project. Tap the "Menu" button, then start the interactive transition by panning from the right screen edge.

Things I've tried:

  • calling -setNeedsStatusBarAppearanceUpdate on any of the navigation and view controllers involved after the transition has been canceled
  • Changing the navigationBar.barStyle to UIBarStyleDefault and back to UIBarStyleBlack

I also verified that the statusBarStyle of my modal navigation controller is set correctly:

(lldb) p (UIStatusBarStyle) [[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentedViewController] preferredStatusBarStyle]
(UIStatusBarStyle) $8 = UIStatusBarStyleLightContent

Still, the status bar is black.

Any further idea what I could try?


Solution

  • To me this looks like a bug (rdar://15902745) in UINavigationController. After a canceled dismissal UINavigationController doesn't query again its presentedViewController for the preferredStatusBarStyle but uses the preferredStatusBarStyle from itself. I worked around this by overwriting -childViewControllerForStatusBarStyle:

    - (UIViewController*)childViewControllerForStatusBarStyle {
        if (self.presentedViewController) {
            return self.presentedViewController.childViewControllerForStatusBarStyle;
        }
    
        return [super childViewControllerForStatusBarStyle];
    }
    

    Then, to animate the change during (and not after) the dismissal, I also overwrote -preferredStatusBarStyle.

    I pushed the workaround to the sample project.