iosswiftuinavigationcontrolleruibarbuttonitemuinavigationitem

Why does setting a custom backBarButtonItem for a UINavigationItem result in double back buttons?


I have a very simple setup. A UINavigationController with a root UIViewController that modifies its navigation item with a custom back button item on viewDidLoad.

    let backButton = UIBarButtonItem(image: backArrowImage,
                                     style: .plain,
                                     target: nil,
                                     action: nil)

    navigationItem.backBarButtonItem = backButton

I'm expecting this to completely replace the system back button with title and the default back arrow icon.

However when I push a new view controller on the stack, the navigation bar draws both the new custom back icon and the system back icon.

This is what I'm seeing:

result

This is what I would expect it to look like:

Expected result


Solution

  • The solution was to set global UINavigationBar appearance. Apparently this has to be done at app launch.

    UINavigationBar.appearance().backIndicatorImage = backArrowImage
    UINavigationBar.appearance().backIndicatorTransitionMaskImage = backArrowImage
    

    With this approach we can preserve title animations and general back button behavior that would not be preserved if supplementing the back button with the leftBarButtonItem.