UINavigationBar changes in iOS13

Apple brings a lot of appearance changes in iOS13 and the navigation bar is one of them.

In iOS13 the default appearance of the large title style navigation bar has changed from translucent to transparent.

Nothing changes much in a plain style table view, the navigation bar will show the color of a table view, in this case, white. For grouped style, there is also some offsetting change.

These are not that big of a change, but if your design relies on this colored bar you might need to tweak your design or add some code to going back to old appearance style.

You get this for free (even you might not want it) when you build your app against iOS13 (Xcode11).

Going back to old-style #

If you want translucent style back put following code in application(_:didFinishLaunchingWithOptions:) .

let appearance = UINavigationBarAppearance ( )

appearance . configureWithDefaultBackground ( )

UINavigationBar . appearance ( ) . scrollEdgeAppearance = appearance

Or if you have colored navigation bar you have to set appearance for both scrollEdgeAppearance and standardAppearance .

let coloredAppearance = UINavigationBarAppearance ( )

coloredAppearance . configureWithOpaqueBackground ( )

coloredAppearance . backgroundColor = . systemPink

coloredAppearance . titleTextAttributes = [ . foregroundColor : UIColor . white ]

coloredAppearance . largeTitleTextAttributes = [ . foregroundColor : UIColor . white ]



UINavigationBar . appearance ( ) . standardAppearance = coloredAppearance

UINavigationBar . appearance ( ) . scrollEdgeAppearance = coloredAppearance

Note that bar color that set with backgroundColor in iOS13 will result in true color, just like when you set barTintColor with isTranslucent = false . I still can't figure out how to make it be a translucent color, luckily that I always hate that translucent color. It hard to make it matched the design I get from a designer.

On the left is bar color with isTranslucent equal to false , on the right the one with isTranslucent equal to true which is the one used in iOS13.

If you want to embrace this change you need to know a new set of API that comes with it, Appearance Customization API.

Appearance Customization API #

There is a new class that represents an appearance which encapsulates all customization options for a navigation bar, UINavigationBarAppearance .

Note that UINavigationBarAppearance is a subclass of UIBarAppearance , which is a base class for other bar appearance, UIToolbarAppearance , UITabBarAppearance . I this article we will focus only navigation bar.

You configure this UINavigationBarAppearance and assign it to new properties in UINavigationBar , standardAppearance , compactAppearance , and scrollEdgeAppearance .

What are standard/compact/scroll edge appearance? #

These 3 appearances represent each presentation style of the navigation bar.

Standard appearance represents a navigation bar in regular height without a large title. This appearance will use to form default for other two, compactAppearance and scrollEdgeAppearance , if you don't specify them.

Compact appearance represents a navigation bar in compact height.

The last one is Scroll edge appearance, based on WWDC session, Modernizing Your UI for iOS 13, this one will be used when navigation associated with a scroll view, but in my test, this one will be used for large title navigation bar even it does not have scroll view.

Scroll edge appearance also applies for navigation bar with search controller. See UINavigationBar changes in iOS13, Part2: UISearchController for more detail.

So to customize your navigation bar what you need to do is create UINavigationBarAppearance and customize it how you want your bar to be and apply it to any of 3 navigation bar appearances. There are many properties you can set I encourage you to check the UINavigationBarApperance's document to find out what properties you can set.

Here is an example of property and the result you would get.

let standard = UINavigationBarAppearance ( )



standard . configureWithOpaqueBackground ( )



standard . backgroundColor = . systemPink

standard . titlePositionAdjustment = UIOffset ( horizontal : - 30 , vertical : 0 )

standard . titleTextAttributes = [ . foregroundColor : UIColor . white ]



let button = UIBarButtonItemAppearance ( style : . plain )

button . normal . titleTextAttributes = [ . foregroundColor : UIColor . systemYellow ]

standard . buttonAppearance = button



let done = UIBarButtonItemAppearance ( style : . done )

done . normal . titleTextAttributes = [ . foregroundColor : UIColor . systemGreen ]

standard . doneButtonAppearance = done



UINavigationBar . appearance ( ) . standardAppearance = standard

One thing I want to highlight here is .configureWithOpaqueBackground method. UIBarAppearance provided 3 methods to configure appearance.



open func configureWithDefaultBackground ( )







open func configureWithOpaqueBackground ( )







open func configureWithTransparentBackground ( )

The description is quite confusing, but in short, these will set styles based on whether you want your bar to be translucent, opaque, or transparent.

Here is the example of what it looks like for configureWithTransparentBackground , configureWithDefaultBackground , and configureWithOpaqueBackground (I set table view background to pink to make translucent more obvious).

Applying appearance to UINavigationBar.appearance() or instance of UINavigationBar will affect every view if you want per view bar appearance you can set UINavigationBarAppearance to UINavigationItem .

let appearance = navigationController ? . navigationBar . standardAppearance . copy ( )



navigationItem . standardAppearance = appearance

And once you've done that, whenever the view controller and navigation item is current, that appearance will be used instead of the navigationBar's base appearance.

This new way of customizing our navigation bar is more flexible and consistent across components. With these changes, I think we can ditch out all the hack we put in all these years to make transparent navigation bar, remove the shadow, etc.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron

Tweet

Share

← Home