1

For an iOS 14+ app I'd like to use navigationItem.backButtonDisplayMode = .minimal to hide the back button title, while still having the title available in the back button's long-press menu. Which works.. however I also want to change the back button image, to replace the default chevron.

But no matter what I try, I can't seem to find a solution that shows a custom back button image without a title, while also not showing a blank space in the back button's long-press menu, and not breaking the slide-to-go-back-gesture.

Anyone tried something similar, and succeeded?

So in the first view controller I show a title:

enter image description here

And then in the pushed view controller I want to show a custom back button image WITHOUT the "one" title (as seen below), and still have the long-press menu say "one" instead of a blank space.

enter image description here

This mostly gets me there actually, except that it breaks the gesture to slide to go back:

override func viewDidLoad() {
  super.viewDidLoad()

  let backImage = UIImage(named: "backImage")?.withRenderingMode(.alwaysOriginal)
  navigationController?.navigationBar.backIndicatorImage = backImage
  navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage

  navigationItem.backButtonDisplayMode = .minimal
}

Update: actually it only seems to break on the simulator, it's all fine on an actual device. I now have a minimal project setup where it all works, now to find out why it doesn't work in my actual big project!

Kevin Renskers
  • 5,156
  • 4
  • 47
  • 95
  • Have your tried [this solution](https://stackoverflow.com/a/39508911/3585796)? works fine to me – Phil Dukhov Oct 02 '21 at 19:45
  • Setting a custom image is not a problem, but I can't get it to work in combination with `navigationItem.backButtonDisplayMode = .minimal` so that I don't get a back button title, but also don't get a blank space in the back button's long press menu. – Kevin Renskers Oct 02 '21 at 21:55

2 Answers2

1

Okay, I finally figured out all the problems I was having.

Basically, this code works just fine:

override func viewDidLoad() {
  super.viewDidLoad()

  let backImage = UIImage(named: "backImage")?.withRenderingMode(.alwaysOriginal)
  navigationController?.navigationBar.backIndicatorImage = backImage
  navigationController?.navigationBar.backIndicatorTransitionMaskImage = backImage

  navigationItem.backButtonDisplayMode = .minimal
}

But I was having problems with the swipe back gesture not working anymore. Turns out, that's a simulator bug, works fine on device. Then there was the problems that the custom back button image didn't actually show up in my view, because of this:

let appearance = UINavigationBarAppearance()
appearance.backgroundColor = .pageBackground
appearance.titleTextAttributes = [.foregroundColor: UIColor.abbey]
appearance.shadowColor = .clear

navigationBar.scrollEdgeAppearance = appearance
navigationBar.standardAppearance = appearance
navigationBar.compactAppearance = appearance

As soon as you set a custom appearance, that completely wipes away the custom back button image. Simple fix, just set these things directly on the navigationBar without involving the appearance.

And now it all works!

Kevin Renskers
  • 5,156
  • 4
  • 47
  • 95
0

To set the image, you can use:

navigationController?.navigationBar.backIndicatorImage = yourBackImage
navigationController?.navigationBar.backIndicatorTransitionMaskImage = yourBackImage

Let's say you have navigation from AVC to BVC.

If you want to disable the long press menu, you can follow this answer.

If you want the long press menu to work with the correct titles, you need to set navigationItem.title for your AVC to the right value, and navigationItem.backBarButtonItem should be nil(it's the default value) for BVC.

If you don't want to display the title in your AVC, you can hide it with titleView:

navigationItem.title = "title for long press navigation menu"
navigationItem.titleView = UIView()
Phil Dukhov
  • 67,741
  • 15
  • 184
  • 220