Transitioning between transparent navigation bar to translucent


Instead of hiding and showing the navigation bar, you can update the alpha for the navigation bar. It will animate smoothly during the transition. For the view controller with transparent nav bar, instead of modifying the nav bar, create a navbar (or just the back button and title etc.) manually in the second controller's view. We will then hide the navbar when transitioning from first view controller to the second one.

On your first controller's viewWillDisappear and on your second view controller's viewWillAppear:, set the navigation bar alpha to zero using self.navigationController.navigationBar.alpha = 0;. Since this is in animation block, this will make the navigation bar disappear during the push animation.

Set the alpha back to one in first controller's viewWillAppear and second controller viewWillDisappear.


In Apple's recently released Remote app I noticed the way in which the navigation bar behaves is unique and I haven't been able reproduce it. When popping the Now Playing view controller the navigation bar remains transparent for the Now Playing view controller and the navigation bar for the library view controller also stays translucent (Screenshot 1). I'm trying to figure out if they are using two navigation controllers or only one. Personally I feel they're using just one for two reasons (1) the interactive pop gesture is enabled; (2) when you press the 'Now Playing' button in the library view controller, just before the now playing screen has finished 'push view controller' animation the navigation bar becomes transparent (Screenshot 2). This is the behaviour I experience when pushing my view controller (which sets the navigation bar to transparent). So my question is: How does Apple present both navigation bars of the two view controllers as if they were individual (as with Screenshot 1), even the bar buttons, navigation title etc... are 100% in opacity when switching (usually when pushing/popping the buttons and titles of the previous view controller fade as the new controller is being pushed). I've tried playing around with the bar tint colour in viewDidAppear and viewWillAppear in both view controllers but cannot reproduce the same behaviour, and cannot prevent the bar buttons from fading.

Gosh I hope I've explained this well, I get confused just thinking about it!

Screenshot 1 (Popping):

Screenshot 2 (Pushing):

Managing a transition from a normal NavigationBar to a transparent one

Have you looked into UIViewControllerTransitionCoordinator?

Each UIViewController has a transitionCoordinator property you can access to perform tasks that are related to a transition.

From the viewWillAppear/viewWillDisappear methods of the UIViewController doing the transition call the animateAlongsideTransition method of the transitionCoordinator:

id <UIViewControllerTransitionCoordinator> coordinator = [self transitionCoordinator];

[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
    // animate the changes in the navigation bar here
} completion:nil];

You don't have to calculate how far to shift everything down, there's a build in property for this. In Interface Builder, highlight your view controller, and then navigate to the attributes inspector. Here you'll see some check boxes next to the words "Extend Edges". As you can see, in the first screenshot, the default selection is for content to appear under top and bottom bars, but not under opaque bars, which is why setting the bar style to not translucent worked for you.

As you can somewhat see in the first screenshot, there are two UI elements hiding below the navigation bar. (I've enabled wireframes in IB to illustrate this) These elements, a UIButton and a UISegmentedControl both have their "y" origin set to zero, and the view controller is set to allow content below the top bar.

This second screenshot shows what happens when you deselect the "Under Top Bars" check box. As you can see, the view controllers view has been shifted down appropriately for its y origin to be right underneath the navigation bar.

This can also be accomplished programmatically through the usage of -[UIViewController edgesForExtendedLayout]. Here's a link to the class reference for edgeForExtendedLayout, and for UIRectEdge

[self setEdgesForExtendedLayout:UIRectEdgeNone];