I implemented a basic UIViewController with a UITableView that\'s wrapped in a UINavigationController. I set prefersLargeTitles
to true:
override fu
In the storyboard I set the Navigation Item's Large Title
to Never
.
In my ViewController's viewDidLoad method I set the following:
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
I had the similar issue. The view is a table view. The property of prefersLargeTitles
is set at viewDidLoad
event. Then I set view's title in viewWillAppear
event.
override open func viewDidLoad() {
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
} else {
// Fallback on earlier versions
}
...
}
override open func viewWillAppear(_ animated: Bool) {
self.navigationItem.title = "something"
...
}
In my prepare segue event, I set navigation item's tile to nil
so that the next view left navigation var item displays "Back" automatically.
override func prepare(for segue: UIStoryboardSegue,
sender: Any?) {
self.navigationItem.title = nil
...
}
The first time the table view displays large title correctly. However, if I select a row to next view and back to the table view, the navigation item's title becomes empty.
After several hours' struggling, I finally find out that the view's title should be set in viewDidAppear
event! It seems that whatever set to view's title in Will
event would be reset by UIKit internally back to nil. So it has to be set in a different event.
override func viewDidAppear(_ animated: Bool) {
self.navigationItem.title = "something"
...
}
override open func viewWillAppear(_ animated: Bool) {
// self.navigationItem.title = "something" // Remove it and set title in Did event!
...
}
Before I introduced this iOS 11 new feature, my app runs OK. It seems that the new feature has some changes in UIKit so that the previous version app may need some updates/changes to make it work.
General changing the behaviour of the navigationBar
should be done in viewWillAppear(_:)
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.prefersLargeTitles = true
}
After doing that it worked fine for me.
I had the same issue (iOS 14, Xcode 12.2).
It only affected navigation controllers displaying table views.
I had originally set tableView.tableFooterView = UIView()
to get rid of extra separators after the last cell. Setting the footer view to nil
fixed the scrolled-up navigation title.
I had a similar issue with navigation bar, but in my case it had a custom title view, and navigation bar remained empty until table view is scrolled down, which triggered UILayoutContainerView
to layout its subviews, one of which are navigation controller's view and navigation bar. I assume the root of it is the same as the large title navigation bar issue.
Anchoring tableView
to the safeAreaLayoutGuide
didn't work out for me, largeTitleDisplayMode
couldn't be other then .never
So I managed to fix it by calling self.navigationController?.view.setNeedsUpdateConstraints
in the top presented controller's viewDidAppear(animated:)
function, or scheduling this call for the next run loop in viewWillAppear(animated:)
, like:
DispatchQueue.main.async {
self.navigationController?.view.setNeedsUpdateConstraints()
}
In this case, navigation bar appeared with the correct content and size along with presenting transition, instead of popping in after transition was completed
What worked for me is setting the self.navigationController?.navigationBar.prefersLargeTitles = true
before calling tableviews reload method.