dank_muffin
dank_muffin

Reputation: 263

How to keep navigation bar title large after pushing view controller from TableView

I have a tableview displaying on a main view controller, and when a row is selected a detail view controller is pushed. I have a large title for the main view controller, and a small/regular title for the detail view controller. They are embedded in a navigation controller and tab bar controller.

Before selecting a row, the main view controller title is large, and when a row is selected the detail view controller title is regular as it should be. However when I return to the main view controller from the detail view controller (via "back" button), the title on the main view controller is no longer large.

I have "prefersLargeTitles" set to true on the main view controller, and "largeTitleDisplayMode" set to never on the detail view controller.

I have tried setting "largeTitleDisplayMode" to always on the main view controller to no avail. I've also tried setting it to automatic on either view controller and seems to have no effect.

I've also tried using "viewWillAppear" and "viewWillDisappear" and setting the title in there, and while it does indeed reset the main view controller title back to large, the animation lags and isn't smooth like it normally is when transitioning from a small title to a large title.

Also I'm pretty new to coding and this is my first app I'm building without using storyboards, so the code could be a mess.

MAIN view controller code:

class HomeViewController: UIViewController {

  let tableView = UITableView()

  override func loadView() {
      super.loadView()
      view.backgroundColor = .white
      self.title = "Home"

      // Set large title
      navigationController?.navigationBar.prefersLargeTitles = true


      // Make navigation bar transparent
      navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
      navigationController?.navigationBar.shadowImage = UIImage()
      navigationController?.navigationBar.isTranslucent = true


}


extension HomeViewController: UITableViewDelegate {

  func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

      let vc = DetailViewController() as DetailViewController

      if indexPath.section == 0 {
          vc.detailTitle = itemsTop[indexPath.row]
      } else if indexPath.section == 1 {
          vc.detailTitle = itemsBottom[indexPath.row]
      } else {
          print("Failed to load title")
      }


      navigationController?.pushViewController(vc, animated: true)

      tableView.deselectRow(at: indexPath, animated: true)
  }

}

DETAIL view controller code:

class DetailViewController: UIViewController {

  var detailTitle: String?

  override func viewDidLoad() {
      super.viewDidLoad()

      title = detailTitle

      // Make nav bar transparent
      navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
      navigationController?.navigationBar.shadowImage = UIImage()
      navigationController?.navigationBar.isTranslucent = true

      // Prevent large title
      navigationController?.navigationBar.prefersLargeTitles = false
  }

}

Upvotes: 7

Views: 5710

Answers (2)

Samir Shaikh
Samir Shaikh

Reputation: 557

try this it's working. In 'HomeViewController'

override func viewDidLoad() {
    super.viewDidLoad()

    navigationController?.navigationBar.prefersLargeTitles = true
}

In 'DetailViewController'

override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationItem.largeTitleDisplayMode = .never
}

Upvotes: 8

Yusuf Ak
Yusuf Ak

Reputation: 781

You need to set navigationController?.navigationBar.prefersLargeTitles to true in viewWillAppear of your main view controller to let it run every time you go back to main.

You can set it to false in viewWillAppear of detail and revert it in viewWillDisappear of detail to prevent it to remain as false as well.

The code for your DetailVC:

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

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

Upvotes: 1

Related Questions