15

In ios 13, Apple introduced the new UINavigationBarAppearance proxy object to set the navigation bar appearance. I've been able to set almost everything I needed except one small thing. The back button's arrow is always rendered with blue tint color and I have no idea how to set it to the color I want. I am using the old [[UINavigationBar appearance] setTintColor:] way, but I think there has to be some way to do it with the UINavigationBarAppearance objects API. Anybody has any idea how?

Roman
  • 949
  • 7
  • 16

2 Answers2

13

The new way of setting the back button color of the appearance (proxy) would be:

let appearance = UINavigationBarAppearance()

// Apply the configuration option of your choice
appearance.configureWithTransparentBackground()
            
// Create button appearance, with the custom color
let buttonAppearance = UIBarButtonItemAppearance(style: .plain)
buttonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.white]

// Apply button appearance
appearance.buttonAppearance = buttonAppearance

// Apply tint to the back arrow "chevron"
UINavigationBar.appearance().tintColor = UIColor.white

// Apply proxy
UINavigationBar.appearance().standardAppearance = appearance

// Perhaps you'd want to set these as well depending on your design:
UINavigationBar.appearance().compactAppearance = appearance
UINavigationBar.appearance().scrollEdgeAppearance = appearance
Attila H
  • 3,616
  • 2
  • 24
  • 37
Justin Ganzer
  • 582
  • 4
  • 15
8

I have a custom navigation controller setup in my app, which modifies navigationBars titleTextAttributes, tintColor and others depending on different scenarios.

Running the app on iOS 13 the backBarButtonItem arrow had default blue tint color. The view debugger showed that only the UIBarButtonItems UIImageView had this blue tint.

What I ended up doing was setting the navigationBar.tintColor twice for it to change the color...

public class MyNavigationController: UINavigationController, UINavigationControllerDelegate {

    public var preferredNavigationBarTintColor: UIColor?

    override public func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }


    public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {

        // if you want to change color, you have to set it twice
        viewController.navigationController?.navigationBar.tintColor = .none
        viewController.navigationController?.navigationBar.tintColor = preferredNavigationBarTintColor ?? .white

        // following line removes the text from back button
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)

    }


The weirdest part when looking for solution was the inconsistent result, which makes me think its related to view life cycle and/or appearance animations or Xcode cache :)

Mark Meyer
  • 3,643
  • 3
  • 23
  • 34
Artur
  • 161
  • 1
  • 3
  • 3
    Can't believe all the hack-fixes that we need to do to support iOS 13 :/ Thanks for the fix btw! – Sreejith Oct 08 '19 at 11:46
  • 1
    Strange, I don't have to set it to `.none` or `nil`, I just give it a color after setting the appearance and it just works – Mark Oct 09 '19 at 16:12