iOS 11 large-title navigation bar not collapsing
Asked Answered
S

8

60

The Apple guy in the What's new in Cocoa Touch WWDC video said that the new large-title navigation bar will magically hook into the top-level scroll view of the underlying view controller and collapse/expand itself automatically while scrolling up and down. (And by "magically", he probably meant that they failed to monkey patch this functionality into the already embarassing UINavigationController-UINavigationBar-UINavigationitem APIs in a usable way, so they had to resort to hooking into some heuristically chosen scroll view behind the scenes)

Even though I was prepared that this "automatic" collapse/expand wouldn't work if I deviate the slightest from the basic UINavigationController + UITableView/UICollectionView setup, it seems that even in this simplest case it doesn't work as expected.

Here's what I have:

A UITabBarController which contains a UINavigationController, which contains a UIViewController, which has a UITableView as its view. Tapping the first cell in the table will push a second view controller on the navigation stack:

storyboard

No code, just the storyboard.

I've checked "Prefers large titles" for the navigation bar to activate large titles. Now, if I run the app and scroll up/down on the table view, the navigation bar stays the same - large - size; it doesn't collapse:

stuck with large title

However, I've found that if I set the second view controller's navigation item to use the small navigation bar (by setting "Large Title" to the value "Never"), then if I open that page and navigate back, the interactive collapse magically starts working on the first page:

interactive collapse works after back navigation

Am I missing something here, or is this feature not working properly? Here's the sample project I'm using: https://github.com/tzahola/iOS-11-Large-Title-Navigation-Bar

And by the way, I'm using the officially released iOS 11, not the betas.

2017-09-23 Update: I've sent a bug report to Apple, and opened a ticket on openradar.me: http://www.openradar.me/radar?id=5017601935671296

Sallyanne answered 22/9, 2017 at 20:54 Comment(4)
I'm experiencing the same exact thing. My gut tells me that it's a bug 😒 – Meleager
@Meleager check my answer below! – Sandbank
@TamásZahola thanks. I'll give it another shot tonight – Meleager
Science I can't comment I'll share the answer I posted https://mcmap.net/q/330509/-hide-large-title-when-scrolling-up – Pouter
S
28

Good news! I've just figured out that if I set "Large Titles" to "Never" on the storyboard, and then set it via code, then it works:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAutomatic;
}

Seems like Apple forgot to handle the case when the navigation item has its largeTitleDisplayMode set via the Interface Builder.

So until they fix this issue, leave "Large Titles" as "Never" on storyboards, and set them via code in viewDidLoad.

You just need to do that to the first view controller. Subsequent view controllers honor the value in storyboard.

Sallyanne answered 23/9, 2017 at 19:8 Comment(3)
Could you please specify, where can I find this "Large Titles" on Storyboards? All I can find is "Prefers large titles" checkmark option on navigation bars. On which controller do you call the above code snippet, on the list or on the detail page? – Quid
@Quid You should select the navigation item on the view controller contained by the navigation controller! – Sandbank
As @TamásZahola explained. It's very important to add that code (and disable "Automatic" / set to "Never" in IB) to the very first (root?) view controller that will be loaded by the navigation controller. If you do that on subsequent view controllers, it won't have any effect! – Carnot
A
43

If there is any other view in addition to tableView, also make sure tableView is on the top of that view(s), right under the Safe Area:

enter image description here

Alembic answered 27/8, 2018 at 8:19 Comment(3)
Thanks! this helped me! – Tingey
This helped me too Thanks! – Suitor
Why though. I have a background gradient I can't put anything behind... – Hydrogeology
S
28

Good news! I've just figured out that if I set "Large Titles" to "Never" on the storyboard, and then set it via code, then it works:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationItem.largeTitleDisplayMode = UINavigationItemLargeTitleDisplayModeAutomatic;
}

Seems like Apple forgot to handle the case when the navigation item has its largeTitleDisplayMode set via the Interface Builder.

So until they fix this issue, leave "Large Titles" as "Never" on storyboards, and set them via code in viewDidLoad.

You just need to do that to the first view controller. Subsequent view controllers honor the value in storyboard.

Sallyanne answered 23/9, 2017 at 19:8 Comment(3)
Could you please specify, where can I find this "Large Titles" on Storyboards? All I can find is "Prefers large titles" checkmark option on navigation bars. On which controller do you call the above code snippet, on the list or on the detail page? – Quid
@Quid You should select the navigation item on the view controller contained by the navigation controller! – Sandbank
As @TamásZahola explained. It's very important to add that code (and disable "Automatic" / set to "Never" in IB) to the very first (root?) view controller that will be loaded by the navigation controller. If you do that on subsequent view controllers, it won't have any effect! – Carnot
W
14

Or instead of changing anything in storyboard, do this:

override func viewDidLoad() {
    super.viewDidLoad()
    if #available(iOS 11.0, *) {
        self.navigationItem.largeTitleDisplayMode = .never
        self.navigationItem.largeTitleDisplayMode = .always
    }
}

No matter which language!

This is because large titles on navigation item decides whether or not to collapse on the basis of large title behaviour on previous screen navigation item title.

Wesla answered 11/10, 2017 at 15:49 Comment(1)
To add on, the documentation states that .always is meant to: "Always display a large title" (which would then presumably collapse), and .automatic, to: "Inherit the display mode from the previous navigation item". So if the main view controller is .always and the children are all .automatic, it should all act as .always. – Houdini
P
7

Make sure that addSubview(tableView) placed before others addSuview(someview)

Puttee answered 11/8, 2020 at 12:14 Comment(3)
Great answer but I have to ask WHY ?! and do you have any documentation reference to this ? – Halle
This is what worked me. Seems that scrollview has to be first subview for auto collapse/expand to work. Thanks. – Excide
wow took me whole day and solution was so simple. – Insignia
C
4

Year 2020, iOS 13.0, this WAS NEVER mentioned here. I literally spent an hour or two for this.

Issue: Large title won't collapse when doing layout programmatically using Snapkit (an autolayout framework)

Solution: SETUP YOUR VIEWS (including navigationController stuff and tableView) inside loadView() NOT in viewDidLoad().

Circulation answered 10/4, 2020 at 12:54 Comment(1)
Ran into a similar issue. Using SnapKit to constrain a table view with make.directionalEdges.equalTo(superview.safeAreaLayoutGuide).inset(insets) meant the animation was broken, using make.directionalEdges.equalToSuperview().inset(insets) was fine. Bizarre. – Suannesuarez
B
2

@TamasZahola @mohamede1945

Guys I had the same problem. I was able to resolve this issue by adding following snippet on my first View Controller of Navigation Controller

navigationController?.navigationBar.prefersLargeTitles = true
Busty answered 18/10, 2017 at 1:26 Comment(2)
Where? Are you using Storyboards? – Tagmeme
Yes, I was using storyboard. – Busty
F
0

It's an odd bug. The fix is to toggle OFF prefersLargeTitles in the storyboard and to set this in viewDidLoad of your nav controller's root vc:

navigationController?.navigationBar.prefersLargeTitles = true
Fina answered 29/8, 2021 at 19:54 Comment(0)
P
0

TableView of its container should be at the top of ViewController's view hierarchy (RootView on screenshot). Otherwise it won't work.

enter image description here

Presley answered 14/12, 2021 at 9:51 Comment(0)

© 2022 - 2024 β€” McMap. All rights reserved.