6

Currently, I have large titles enabled for the navigation bar with the following code in the viewdidLoad of the ViewController:

navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationItem.largeTitleDisplayMode = .automatic
        
let date = Date()
let formatter = DateFormatter()
formatter.dateFormat = "MMMM dd"
let result = formatter.string(from: date)

self.title = "This is a Test\n\(result)"

var count = 0
for item in(self.navigationController?.navigationBar.subviews)! {
    for sub in item.subviews {
        if sub is UILabel {
            if count == 1 {
                break;
            }
            let titleLab :UILabel = sub as! UILabel
            titleLab.numberOfLines = 0
            titleLab.text = self.title
            titleLab.lineBreakMode = .byWordWrapping
            count = count + 1
        }
    }
}
self.navigationController?.navigationBar.layoutSubviews()
self.navigationController?.navigationBar.layoutIfNeeded()

How can I present a completely different title when the navigation bar is collapsed in a "normal state" where the bar is no longer large?

Ortwin Gentz
  • 52,648
  • 24
  • 135
  • 213

2 Answers2

11

You can observe the bounds of the navigationBar and change the title using a check on the height of the navigationBar.

1. for Small Title, height of navigationBar = 44

2. for Large Title, height of navigationBar > 44

class VC: UIViewController {
    var observer: NSKeyValueObservation?

    override func viewDidLoad() {
        super.viewDidLoad()
        self.observer = self.navigationController?.navigationBar.observe(\.bounds, options: [.new], changeHandler: { (navigationBar, changes) in
            if let height = changes.newValue?.height {
                if height > 44.0 {
                    //Large Title
                    self.title = "Large Title"
                } else {
                    //Small Title
                    self.title = "Small Title"
                }
            }
        })
    }
}

enter image description here

PGDev
  • 23,751
  • 6
  • 34
  • 88
  • Quick side question, if you notice my original code splits the title into two rows: self.title = `“This is a Test\n\(result)"` Is it possible to make each row a different color? –  Jun 12 '19 at 19:00
  • Can you please take a look this post? https://stackoverflow.com/questions/56569515/change-the-color-of-text-in-this-custom-navigation-bar-with-two-rows –  Jun 12 '19 at 19:55
  • 1
    I found that there were issues with this method when scrolling and navigating in a navigation stack. Observing the frame height instead of the bounds height seems to have fixed it. – Drew Apr 08 '21 at 00:15
  • I can confirm that there is an issue with observing bounds, it shows 45, 46, 47 instead of 44. With `.frame` works fine. – ChikabuZ Mar 17 '22 at 09:27
  • Does anyone know about a SwiftUI equivalent to this? :) – Nicolai Harbo Jan 17 '23 at 11:56
3
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let heightForCollapsedNav = UINavigationController().navigationBar.frame.size.height
    let navHeight = navigationController!.navigationBar.frame.size.height
    navigationController?.navigationBar.topItem?.title = navHeight <= heightForCollapsedNav  ? "Collapsed" : "Large"
}
Gal
  • 197
  • 1
  • 12