Under iOS 13, if you setup a scrollable root view controller (such as a UITableViewController) in a navigation controller and then put that navigation controller in the detail pane of a UISplitViewController, then the nav bar's background isn't visible when the scrollable content is at the top.
You can see this by creating a new iOS project based on the Master/Detail template. Then modify the storyboard to use a UITableViewController inside the detail pane's nav controller. Put the device/simulator in Light Appearance mode (it shows the problem better than Dark mode). Run the app and notice the nav bar area is the same color as the table view background. Now scroll the table view up and the nav bar color changes to the standard light gray. Let the table view return to the top and the nav bar color disappears again.
I've only seen this in the detail pane of a split view controller.
How do you turn off this "feature" so that the nav bar looks normal just like every other nav bar used anywhere else other than the detail pane of a split view controller?
There are no relevant API changes for UISplitViewController
or UISplitViewControllerDelegate
. There's nothing in UINavigationController
either.
After some digging I found one workaround but I'd love to find a way to avoid having to do this.
The UINavigationBar
class now has some new properties for setting its appearance. Oddly, none of these are mentioned under the "Customizing the Appearance of a Navigation Bar" in the documentation for UINavigationBar
.
There are three new properties in iOS 13:
standardAppearance
compactAppearance
scrollEdgeAppearance
All three are of type UINavigationBarAppearance
.
Only the first one is set by default.
Even though scrollEdgeAppearance
is nil
, the detail pane of a split controller acts as if this has been set with the backgroundColor
set to the clear
color.
So the workaround is to add the following line to the viewDidLoad
method of the navigation controller's root view controller:
navigationController?.navigationBar.scrollEdgeAppearance = navigationController?.navigationBar.standardAppearance
Why is this needed only in this one case? Is there a more correct solution other than adding this code?
I noticed that none of Apple's apps (Mail, Notes, and Files at least) seem to use this "feature".
The workaround you found is the 'official' way to disable this behavior, as explained in a thread on Twitter by David Duncan who is on the iOS System Experience team at Apple.
An Apple app that does not disable this behavior is the Settings app.