Search code examples
iosswiftuinavigationbarios15uinavigationbarappearance

Using UIBarButtonItemAppearance have both the system and the custom back button images


I am using UIBarButtonItemAppearance for the first time and I'm confused on how to put a custom image for the back button.

This is how I do it:

private func createBarButtonAppearence(_ color: UIColor, textColor: UIColor)  -> UINavigationBarAppearance {
        let appearance = UINavigationBarAppearance()
        appearance.titleTextAttributes = [.foregroundColor: textColor]
        appearance.largeTitleTextAttributes = [.foregroundColor: textColor]
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = color
        
        let back = UIBarButtonItemAppearance()
        back.normal.backgroundImage = UIImage(named: "white_back_arrow")
        appearance.backButtonAppearance = back
        return appearance
    }

This successfully puts the "white_back_arrow" image as the back button but it also keeps the original iOS back button image as it shows:

enter image description here

How can I avoid this behaviour?


Solution

  • You are setting the background image of the button. That doesn't change the button's image.

    Try it like this:

    private func createBarButtonAppearence(_ color: UIColor, textColor: UIColor)  -> UINavigationBarAppearance {
        let appearance = UINavigationBarAppearance()
        appearance.titleTextAttributes = [.foregroundColor: textColor]
        appearance.largeTitleTextAttributes = [.foregroundColor: textColor]
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = color
        
        // do this
        if let img = UIImage(systemName: "white_back_arrow") {
            appearance.setBackIndicatorImage(img, transitionMaskImage: img)
        }
    
        // don't do this:
        //let back = UIBarButtonItemAppearance()
        //back.normal.backgroundImage = UIImage(named: "white_back_arrow")
        //appearance.backButtonAppearance = back
        
        return appearance
    }