11

We have two UIViewController with an UINavigationController.

In the first presented VC inside of viewWillAppear(_ animated: Bool) we do:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if #available(iOS 11.0, *) {
            navigationController?.navigationBar.prefersLargeTitles = true
            navigationController?.navigationItem.largeTitleDisplayMode = .always
        }
 ....

Inside of the second VC we deactive that behaviour with inside of viewWillAppear(_ animated: Bool):

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if #available(iOS 11.0, *) {
        navigationController?.navigationBar.prefersLargeTitles = false
    }
...

The transition animation to the second VC is smooth while tapping automatic generated back button causes the navigation controller title to create a strange jump to large title instead of the normal grow to large title animation as it does for example in the Messages App.

If i tap the tabbar icon as "back" operation, it does the right transition animation.

Any idea what could cause that issue or how i can fix it?

bemeyer
  • 6,154
  • 4
  • 36
  • 86
  • Possible duplicate of [Hide large title when scrolling up](https://stackoverflow.com/questions/45144324/hide-large-title-when-scrolling-up) – bemeyer Oct 16 '17 at 13:21

5 Answers5

22

on the second view controller set the largeTitleDisplayMode to .never you won't need to set the prefersLargeTitles to false.

To clarify things here, you've to set the largeTitleDisplayMode directly for the navigationItem of the view controller, not the navigation controller!

self.navigationItem.largeTitleDisplayMode = .never // This fixes the issue
self.navigationController?.navigationItem.largeTitleDisplayMode = .never // This doesn't work / Title will stay large
Pascal_AC
  • 541
  • 4
  • 17
dave
  • 246
  • 2
  • 2
  • 1
    This will cause the nav bar to stay large but the back animation looks right. I want that the second VC does have a "small title", the first one a large one. It only decreases the title to a small one if i set `prefersLargeTitles` to false. – bemeyer Sep 28 '17 at 12:14
  • @BennX, this is a proper solution, I had the same problem and I have just tested it, thanks dave! – Ivan Ičin Oct 07 '17 at 22:52
  • Add `self.navigationItem.largeTitleDisplayMode = .never` in `viewDidLoad` instead of in `viewWillAppear` – El Belga Jul 04 '18 at 11:28
  • Seriously, this gets me *every time*. Apple are driving me insane with their insane layout defaults. – Echelon Jul 19 '19 at 16:35
2

@dave's answer worked for me! Thanks! Here's the code that I used in its entirety:

FirstViewController:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    if #available(iOS 11.0, *) {
        navigationItem.largeTitleDisplayMode = .always
            navigationController?.navigationBar.prefersLargeTitles = true
        }
    }
}

SecondViewController:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if #available(iOS 11.0, *) {
            navigationItem.largeTitleDisplayMode = .never
        }
    }
}
Mark Jeschke
  • 274
  • 1
  • 6
1

One should make force layout of navigation bar right after switching off large title

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    
    navigationController?.navigationBar.prefersLargeTitles = false
    navigationController?.navigationBar.layoutIfNeeded()
}

This cancels out large navigation title immediately.

malex
  • 9,874
  • 3
  • 56
  • 77
0

I had the same transition bug: from large title to small one or backwards. It was not growing/diminishing from one state to the another, but it was staying ugly on the screen for 1 sec, then just jumping from large to small or vice-versa.

The simple solution:

Make sure each view controller has a navigationItem in the Storyboard.

Navigation Item inside the view stack.

And for each navigationItem, set the corresponding Large Title value:

Navigation item attributes inspector

Also, you don't need to set anything in viewDidLoad,viewWillAppear, etc. related to largeTitle. Just what I showed above.

Starsky
  • 1,829
  • 18
  • 25
0

For me it was something completely different. In my project we set a custom back button without title on every VC. Standard way to do this for ages was to set an empty BarButtonItem like this:

navigationItem.backBarButtonItem = UIBarButtonItem()

Removing that line fixed the jumping back button when moving from a VC with large title to one without large title. Still having design requirement I found out that since iOS 14 this can be done much more neatly:

navigationItem.backButtonDisplayMode = .minimal

So just replace setting a new BarButtonItem with setting the display mode.

JanMensch
  • 1,720
  • 1
  • 18
  • 27