tech_human
tech_human

Reputation: 7140

Setting view's header text in navigation bar

I have a sheet on which I wish to show the title of the view in a specific way. The title should be leading and should not be horizontally alignment with tool bar trailing item, but should be below it. Please refer the attached screenshots since it's easier to explain it that way.

Code:

import Foundation
import SwiftUI

struct ContentView: View {
    @State private var showSheet = false

    var body: some View {
        VStack {
            Text("Hello World")
        }
        .onAppear {
            showSheet = true
        }
        .sheet(isPresented: self.$showSheet) {
            SheetA()
        }
    }
}

struct SheetA: View {
    @Environment(\.presentationMode) private var presentationMode
    
    var body: some View {
        NavigationStack {
            ZStack {
                Color.gray.opacity(0.1).ignoresSafeArea(.all)
                VStack {
                    Text("This is sheet A. Navigation title should be below 'Done' button")
                }
            }
            .toolbarBackground(Color.gray.opacity(0.1), for: .navigationBar)
            .toolbarBackground(.visible, for: .navigationBar)
            .navigationBarTitleDisplayMode(.large)
            .toolbar {
                ToolbarItem(placement: .topBarLeading) {
                    VStack {
                        Text("").font(.body.bold()).foregroundStyle(Color.primary)
                        ScrollView(.horizontal, showsIndicators: false) {
                            Text("Hello World. How are you?").font(.largeTitle.bold())
                                .foregroundStyle(Color.primary)
                        }
                    }
                    .padding(.top, 40.0)
                    .padding(.bottom, 10.0)
                }
                
                ToolbarItem(placement: .topBarTrailing) {
                    Button {
                        presentationMode.wrappedValue.dismiss()
                    } label: {
                        Text("Done").font(.body.bold()).foregroundStyle(Color.blue)
                    }
                }
            }
            .interactiveDismissDisabled(presentationMode.wrappedValue.isPresented) /// disable dismiss with a drag/slide-down.

        }
    }
}

What I want:

enter image description here

What I am getting with my code:

enter image description here

I want "Hello World - How are you?" line right above the navigation bar line and the text should cover the space below 'Done' button as well, just like it does in the first screenshot.

How do I achieve this?

Edit: Adding some more details to avoid the confusion. This title text is dynamic, so it could be longer. If it's long, then I would like to either word wrap it onto next line or wrap it into a horizontal scroll view so user can scroll it to view entire text. In my code, I am already wrapping "Text("Hello World. How are you?")" inside a horizontal scroll view.

Upvotes: 0

Views: 88

Answers (1)

tech_human
tech_human

Reputation: 7140

I was able to solve it without setting the title as navigation bar title, but instead adding it to view's body. Still working on the divider, but this is very close to what I am looking for.

import Foundation
import SwiftUI

struct ContentView: View {
    @State private var showSheet = false

    var body: some View {
        VStack {
            Text("Hello World")
        }
        .onAppear {
            showSheet = true
        }
        .sheet(isPresented: self.$showSheet) {
            SheetA()
        }
    }
}

struct SheetA: View {
    @Environment(\.presentationMode) private var presentationMode
    
    var body: some View {
        NavigationStack {
            VStack {
                VStack {
                    ScrollView(.horizontal, showsIndicators: false) {
                        Text("Hello World - How are you? This is long text.").font(.largeTitle.bold())
                    }
                    
                    Divider().frame(height: 5.0)
                }
                .padding(.leading, 10.0)
                .padding(.top, -10.0)
                .padding(.bottom, 70.0)
   
                VStack {
                    Text("This is sheet A. Navigation title should be below 'Done' button")
                }
                
                Spacer()
            }
            .navigationBarTitle("" ,displayMode: .large)
            .toolbarBackground(Color.gray.opacity(0.1), for: .navigationBar)
            .navigationBarTitleDisplayMode(.large)
            .toolbar {
                ToolbarItem(placement: .topBarTrailing) {
                    Button {
                        presentationMode.wrappedValue.dismiss()
                    } label: {
                        Text("Done").font(.body.bold()).foregroundStyle(Color.blue)
                    }
                }
            }
            .interactiveDismissDisabled(presentationMode.wrappedValue.isPresented)
        }
    }
}

Upvotes: 0

Related Questions