iosswiftswiftui

How to make an entire bottom toolbar clickable in SwiftUI?


I am trying to make a bottom toolbar with a Text clickable but it doesn't work.

I tried doing this:

ToolbarItem(placement: .bottomBar) {
    Button(action: {
        print("toolbar tapped!")
    }) {
        HStack {
            Spacer()
            Text("Toolbar")
            Spacer()
        }
    }
}   

But content in bottom bar completely disappears


Solution

  • If you use button style .borderless then you can widen the button by applying .frame(maxWidth: .infinity) to the label:

    ToolbarItem(placement: .bottomBar) {
        Button {
            print("toolbar tapped!")
        } label: {
            Text("Toolbar")
                .padding(.vertical)
                .frame(maxWidth: .infinity)
                .background(.yellow)
                .contentShape(Rectangle())
        }
        .buttonStyle(.borderless)
    }
    

    If you comment out the yellow background, the button can still be tapped across the full width of the toolbar. This is due to the modifier .contentShape. So this modifier is important if the button has no background.

    You can also use a custom ButtonStyle to encapsulate the styling:

    struct ToolbarButton: ButtonStyle {
        func makeBody(configuration: Configuration) -> some View {
            configuration.label
                .foregroundStyle(.link)
                .padding(.vertical)
                .frame(maxWidth: .infinity)
                .background(.yellow)
                .opacity(configuration.isPressed ? 0.2 : 1)
                .contentShape(Rectangle())
        }
    }
    

    Example use:

    struct ContentView: View {
        var body: some View {
            NavigationStack {
                Text("Toolbar example")
                    .toolbar {
                        ToolbarItem(placement: .bottomBar) {
                            Button("Toolbar") {
                                print("toolbar tapped!")
                            }
                            .buttonStyle(ToolbarButton())
                        }
                    }
            }
        }
    }
    

    Screenshot