I want to show a tip on a button that will open a modal sheet on tap. The state if the sheet should be presented is held in an ObservableObject
view model:
@MainActor class ViewModel: ObservableObject {
@Published var showSheet = false
}
struct ContentView: View {
var tip = PopoverTip()
@ObservedObject var viewModel = ViewModel()
var body: some View {
Button(action: {
viewModel.showSheet.toggle()
}, label: {
Text("Button")
})
.popoverTip(tip)
.sheet(isPresented: $viewModel.showSheet) {
Text("Sheet")
}
}
}
Here is the issue: When the tip is dismissed by tapping outside of it instead of tapping the close button, the tip will always reappear when tapping the button instead of showing the sheet. So effectively there is no way of triggering the actual button action, the tip will always pop up again and prevent the sheet from appearing.
This is only an issue when using an ObservableObject
to track the sheet state. When using a @State var showSheet: Bool
inside the view itself instead, the sheet is shown as expected when tapping the button.
It seems to be an issue of timing: Attempting to show the sheet somehow causes the view to be re-evaluated, which causes the tip to reappear (since it wasn't dismissed via close action). And since the tip is presented using modal presentation, the sheet can't be presented anymore.
Is this a bug, or is there a simple way to avoid this issue?