I'm trying to apply multiple sheet view modifiers on a root view powered by a boolean bindings that are evaluated so that only one modal presentation will be in effect at a time. Here is a sample code:
struct ContentView: View {
@State var counter: Int = 0
@State var isPresentingA: Bool = false
@State var isPresentingB: Bool = false
var body: some View {
VStack {
HStack {
Button("-") { self.counter -= 1 }
Text("\(self.counter)")
Button("+") { self.counter += 1 }
}
Button("Modal") {
self.isPresentingA = self.counter % 2 == 0
self.isPresentingB = self.counter % 2 != 0
}
}
.sheet(isPresented: $isPresentingA) {
Text("A")
}
.sheet(isPresented: $isPresentingB) {
Text("B")
}
}
}
With this code the first sheet is never presented, only the last presentation actually happens. When adding a breakpoint into the content closure of the first sheet modifier I see that it is called as expected but no screen is presented. When counter is updated and a button is pressed again the second modal screen is presented as expected.
Question: is it expected or a bug and if it's expected then why? What's the best practice for applying sheet modifier in general, should it be applied on controls triggering the presentation (in that case same button would trigger both presentations any way and the result will be the same)?
My final goal is to abstract navigation details out of the view presenting the content, that's why the modifiers are applied on the whole view rather than to its different children.
Workaround: instead of applying sheet modifier on the root view apply it on empty buttons put with a root view in a z-stack
var body: some View {
ZStack {
VStack { ... }
Button(action: {}) { EmptyView() }
.sheet(isPresented: $isPresentingA) {
Text("A")
}
Button(action: {}) { EmptyView() }
.sheet(isPresented: $isPresentingB) {
Text("B")
}
}
}