helloimbrando
helloimbrando

Reputation: 655

NavigationStack title loads inline instead of large when sheet is presented

One of my views loads in a bottom sheet. It has its own NavigationStack with a title. Problem is that whenever the view is loaded, the title (set on ".automatic") always loads ".inline" instead.

The same happens even if I force the .navigationBarTitleDisplayMode to ".large". The title only goes to ".large" if I scroll the view.

Tried to look into this question but it's about adding the .navigationViewStyle which will soon be deprecated (and applies to NavgationView, not NavigationStack). Is there a way to make the title load .large?

My code for the view inside the bottom sheet:

NavigationStack {
    Form {
        // some code
    }

    .navigationTitle("Title")
    .navigationBarTitleDisplayMode(.large)
}

Upvotes: 4

Views: 1812

Answers (4)

theogood
theogood

Reputation: 138

The accepted answer doesn't work for me. Here's a fix that works on iOS 17. Use NavigationView instead of NavigationStack.

/* NavigationStack { DON'T USE THIS */
NavigationView {

    Form {
        // some code
    }

    .navigationTitle("Title")
    .navigationBarTitleDisplayMode(.large)
}

Just note, XCode says "NavigationView will be deprecated in a future version of iOS".

Upvotes: 1

pxlshpr
pxlshpr

Reputation: 1111

I'm encountering the same annoying bug. Here's my workaround for now:

import SwiftUI

struct BottomSheet: View {

    @State var hasAppeared: Bool = false
    
    var body: some View {
        NavigationStack {
            Group {
                if hasAppeared {
                    form
                } else {
                    Color.clear
                }
            }
            .onAppear(perform: appeared)
            .navigationTitle("Title")
            .navigationBarTitleDisplayMode(.large)
        }
    }
    
    var form: some View {
        Form {
            Text("Form")
        }
    }
    
    func appeared() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
            withAnimation(.snappy) {
                self.hasAppeared = true
            }
        }
    }
}

I'm initially displaying Color.clear instead of the form—this is crucial as EmptyView() doesn't cut it.

Then, a split second after it appears I set a flag hasAppeared that swaps in the form.

This fixes the issues and the transition from Color.clear to the form isn't noticeable.

Upvotes: 5

Mojtaba Hosseini
Mojtaba Hosseini

Reputation: 119931

You can work around that by using:

UINavigationBar.appearance().prefersLargeTitles = true

Put it in the init() or onAppear as it changes all navigation titles in the entire app and also you may want to disable it in onDisappear.

Upvotes: 2

Hezy Ziv
Hezy Ziv

Reputation: 5558

you need to share your code, but for now you can force the title after view appear

.onAppear {
    UITableView.appearance().largeTitleDisplayMode = .always
}

Upvotes: 0

Related Questions