TheSD
TheSD

Reputation: 883

Large title to regular title and back

I want to have one view with a large title then push another view with a regular title and then return back to previous with a large title.

I have tried setting prefersLargeTitles = true in the first view in viewWillAppear and setting prefersLargeTitles = false in the second view in viewWillAppear. This works, but the title does not have a smooth transition like it normally does when going from the second view to the first view.

class FirstViewController: UIViewController {

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    navigationController?.navigationBar.prefersLargeTitles = true
  }

  func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    if let secondViewController = secondViewController.storyboardInstance() {
      self.navigationController?.pushViewController(secondViewController, animated: true)
    }
  }
}

class SecondViewController: UIViewController {

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

}

Upvotes: 0

Views: 1711

Answers (3)

Thomas Sivilay
Thomas Sivilay

Reputation: 326

So you are relying on the default value of largeTitleDisplayMode which is .automatic and you are using prefersLargeTitles to be first true then false. There's nothing wrong about this, but I do believe that the .automatic is a bit confusing because it will take any previous value instead of being set on only the first view controller of a navigation controller.

If you can, I will instead do this:

  • FirstVC with largetitleDisplayMode = .always and prefersLargeTitle = true
  • SecondVC with largeTitleDisplayMode = .never and prefersLargeTitle = true (yes.. it has to be true..)

The SecondVC has to use prefersLargeTitle = true because from Apple documentation we can read this:

If the prefersLargeTitles property of the navigation bar is false, this property has no effect and the navigation item’s title is always displayed as a small title.

I've write an article that dig a little bit more around this topic where I also explain how to fix .automatic https://www.morningswiftui.com/blog/fix-large-title-animation-on-ios13

Upvotes: 2

Mitemmetim
Mitemmetim

Reputation: 742

Did you maybe change the font of the back button in the second view? This led to a strange transition of the title in my case. I could solve this by setting the the font not only for the normal state, but also for the highlighted state.

UIBarButtonItem.appearance().setTitleTextAttributes([kCTFontAttributeName as NSAttributedStringKey: UIFont(name: "Futura", size: 17)!], for: .normal)

UIBarButtonItem.appearance().setTitleTextAttributes([kCTFontAttributeName as NSAttributedStringKey: UIFont(name: "Futura", size: 17)!], for: .highlighted)

Upvotes: 0

Alexandre Gaubil
Alexandre Gaubil

Reputation: 199

You can set the prefersLargeTitlesproperty to false in the viewWillDisappear method of the FirstViewController. Something like this should work:

class FirstViewController: UIViewController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.navigationBar.prefersLargeTitles = true
    }

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

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if let secondViewController = secondViewController.storyboardInstance() {
            self.navigationController?.pushViewController(secondViewController, animated: true)
        }
    }
}

Upvotes: 0

Related Questions