1
votes

Xcode 12 beta 6

There is a button in toolbar, its label text is binding to a state var buttonTitle. I want to tap this button to trigger a sheet view, select to change the binding var.

After back to content view, the button's title is updated. But if you tap the button again, it not work.

Code:

struct ContentView: View {
    @State var show = false
    @State var buttonTitle = "button A"

    var body: some View {
        NavigationView {
            Text("Hello World!")
                .toolbar {
                    ToolbarItem(placement: .principal) {
                        Button {
                            show.toggle()
                        } label: {
                            Text(buttonTitle)
                        }
                        .sheet(isPresented: $show) {
                            SelectTitle(buttonTitle: $buttonTitle)
                        }
                    }
                }
        }
    }
}

struct SelectTitle: View {
    @Environment(\.presentationMode) var presentationMode
    @Binding var buttonTitle: String

    var body: some View {
        Button("Button B") {
            buttonTitle = "Button B"
            presentationMode.wrappedValue.dismiss()
        }
    }
}
2

2 Answers

1
votes

It is known toolbar-sheet layout issue, see also here. You can file another feedback to Apple.

Here is a workaround for your case - using callback to update toolbar item after sheet closed. Tested with Xcode 12b5.

struct ContentView: View {
    @State var show = false
    @State var buttonTitle = "button A"

    var body: some View {
        NavigationView {
            Text("Hello World!")
                .toolbar {
                    ToolbarItem(placement: .principal) {
                        Button {
                            show.toggle()
                        } label: {
                            Text(buttonTitle)
                        }
                        .sheet(isPresented: $show) {
                            SelectTitle(buttonTitle: buttonTitle) {
                                self.buttonTitle = $0
                            }
                        }
                    }
                }
        }
    }
}

struct SelectTitle: View {
    @Environment(\.presentationMode) var presentationMode

    @State private var buttonTitle: String
    let callback: (String) -> ()

    init(buttonTitle: String, callback: @escaping (String) -> ()) {
        _buttonTitle = State(initialValue: buttonTitle)
        self.callback = callback
    }

    var body: some View {
        Button("Button B") {
            buttonTitle = "Button B"
            presentationMode.wrappedValue.dismiss()
        }
        .onDisappear {
            callback(buttonTitle)
        }
    }
}
1
votes

Move sheet(...) outside of ToolbarItem scope like this:

NavigationView {
  ..
}.sheet(...)