swiftuibuttonuiimageuinavigationbaruiappearance

Use UINavigationBar appearance "back" icon for custom button?


I need to achieve a custom navigation bar's "< back" button as seen in the push segue, but on a modal.

enter image description here

I want to avoid too much hard-coding and found out about the property UINavigationBar.appearance().backIndicatorImage and UINavigationBar.appearance().backIndicatorTransitionMaskImage.

I want to use these to put my own text beside them for my button, since using a .png doesn't look as natural as the real thing.

I tried this but the UIImage from those properties returns as nil.

func addBackButton() {
    let backButton = UIButton(type: .custom)
    backButton.setImage(UINavigationBar.appearance().backIndicatorImage, for: .normal)
    backButton.imageView?.contentMode = .scaleAspectFit
    backButton.setTitle("Back", for: .normal)
    backButton.setTitleColor(backButton.tintColor, for: .normal)
    
    self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
}

Solution

  • UINavigationBar.appearance().backIndicatorImage is an optional value, therefore you won't be able to get the system default chevron from this. Rather, the system will use the image provided here if not null, otherwise revert to the system default.

    If targeting iOS 13+, you can make use of Apple's SF Symbols, in particular the back button icon is referred to as chevron.left. To use this, call UIImage(systemName: "chevron.left"). For earlier versions of iOS, you'll have to use an image set asset. You could target all versions of iOS using if #available(iOS 13.0, *) { ... } else { ... }, where you display the system image if on iOS 13+ for improved UI appearance.

    func addBackButton() {
        let backButton = UIButton(type: .custom)
        if #available(iOS 13.0, *) {
            backButton.setImage(UIImage(systemName: "chevron.left"), for: .normal)
        }
        else {
            backButton.setImage(UIImage(named: "backChevon"), for: .normal)
        }
        backButton.imageView?.contentMode = .scaleAspectFit
        backButton.setTitle("Back", for: .normal)
        backButton.setTitleColor(backButton.tintColor, for: .normal)
        
        self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
    }