SwiftUI toolbar .bottomBar button doesn't trigger when user configures accessibility1 size or larger

101 Views Asked by At

How can I accommodate user accessibility sizes with a bottomBar button?

With accessibility1 or larger user-configured in iOS, a bottomBar button fails to trigger. Smaller font sizes work. Configuring the toolbar placement to .navigation works.

Details: Navigate from ContentView > FirstView > SecondView, then back to the FirstView via the "Goodbye" bottomBar button displays the FirstView. Then FirstView's "Goodbye" button does not trigger. There is a user-workaround: in this situation, scroll the FirstView down to hide the Goodbye button, release, it returns, then press and it works. Code is below.

struct ContentView: View {
@State var showFirstView: Bool = false
var body: some View {
    NavigationStack {
        Image(systemName: "globe")
            .imageScale(.large)
            .foregroundColor(.accentColor)
        Text("Hello, world!")
        Button("First View") { showFirstView = true }
    }
    .sheet(isPresented: $showFirstView) {
        FirstView()
    }
}

struct FirstView: View {
@Environment(\.dismiss) var dismiss
@State var showSecondView: Bool = false
var body: some View {
    NavigationStack {
        VStack {
            Text("First View")
            Button("Second View") { showSecondView = true }
        }
        .toolbar {
            // On return from SecondView with accessibility1
            // or large text size configured, the button below
            // does not trigger (even with a programmatically limited
            // font size via .dynamicTypeSize).
            
            // However, scroll the view down slightly to hide the button,
            // let it return on screen, then the Goodbye button works.
            ToolbarItem(placement: .bottomBar) {
                Button("Goodbye") { dismiss() }
            }
        }
    }
    .sheet(isPresented: $showSecondView) {
        SecondView()
    }
}

struct SecondView: View {
@Environment(\.dismiss) var dismiss
var body: some View {
    NavigationStack {
        VStack { Text("Second View") }
        .toolbar {
            ToolbarItem(placement: .bottomBar) {
                Button("Goodbye") { dismiss() }
            }
        }
    }
}
1

There are 1 best solutions below

2
SwiftAero On

The technique @Asperi shared in the post, StackOverflow Toolbar disappears when going back, resolves my problem. See Update (1), Update (2), and Update (3) below.

struct FirstView: View {
@Environment(\.dismiss) var dismiss
@State var showSecondView: Bool = false
@State private var refresh = UUID() // <- Update (1)
var body: some View {
    NavigationStack {
        VStack {
            Text("First View")
            Button("Second View") { showSecondView = true }
        }
        .toolbar {
            // On return from SecondView with accessibility1
            // or larger text size configured, the button below
            // does not trigger (even with a programmatically limited
            // font size via .dynamicTypeSize).
            
            // However, scroll the view down slightly to hide the button,
            // let it return on screen, then the Goodbye button works.
            // Or, change placement to .navigation and it works as expected.
            ToolbarItem(placement: .bottomBar) {
                Button("Goodbye") { dismiss() }
            }
        }.id(refresh) // <- Update (2)
    }
    .sheet(isPresented: $showSecondView) {
        SecondView()
            .onDisappear { refresh = UUID() } // <- Update (3)
    }
}

}