# Multiple sheet view modifiers on the same view

**URL:** <https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267>\
**Category:** Using Swift\
**Tags:** off-topic, swiftui\
**Created:** [April 10, 2020, 10:54pm UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267 "2020-04-10T22:54:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![ilyapuchka](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ilyapuchka/32/3327_2.png) [@ilyapuchka](https://forums.swift.org/u/ilyapuchka)\
**Post date:** [April 10, 2020, 10:54pm UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267/1 "2020-04-10T22:54:58Z")

</div>

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:

```swift
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

```swift
    var body: some View {
        ZStack {
            VStack { ... }

            Button(action: {}) { EmptyView() }
            .sheet(isPresented: $isPresentingA) {
                Text("A")
            }

            Button(action: {}) { EmptyView() }
            .sheet(isPresented: $isPresentingB) {
                Text("B")
            }
        }
    }

```

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [April 10, 2020, 11:30pm UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267/2 "2020-04-10T23:30:32Z")

</div>

Most of the time, I'd do this:

```swift
enum SheetChoice: Hashable, Identifiable {
  case a, b

  var id: SheetChoice { self }
}

struct ContentView: View {
  @State var sheetState: SheetChoice?

  var body: some View {
    VStack {
      ...
    }
    .sheet(item: $sheetState) { item in
      if item == .a {
        Text("A")
      } else {
        Text("B")
      }
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![ilyapuchka](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ilyapuchka/32/3327_2.png) [@ilyapuchka](https://forums.swift.org/u/ilyapuchka)\
**Post date:** [April 11, 2020, 7:14am UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267/3 "2020-04-11T07:14:31Z")

</div>

Thanks, this will work but this is not the design I’d want to achieve where the child view presenting content should expose opaque signals for presentation logic, so the parent shouldn’t deconstruct those conditions. Having a separate piece of state just to track modal presentation feels like going back to uikit

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [April 11, 2020, 12:27pm UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267/4 "2020-04-11T12:27:56Z")

</div>

To me, using separate tracking state doesn’t make much sense since it allows for _invalid_ state like

```swift
isPresentingA == true
isPresentingB == true

```

You could of course proof that your own program disallow such state, but then you’re not taking advantage of the type system.

---

<div class="post-metadata">

**Author:** ![ilyapuchka](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ilyapuchka/32/3327_2.png) [@ilyapuchka](https://forums.swift.org/u/ilyapuchka)\
**Post date:** [April 11, 2020, 12:40pm UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267/5 "2020-04-11T12:40:21Z")

</div>

True, but note that this code is for demonstration purposes only and the state management is not the source of the described problem. Instead of separate boolean bindings it can be whatever else, including enum as in your example.

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [April 11, 2020, 12:54pm UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267/6 "2020-04-11T12:54:54Z")

</div>

If it’s the same variable underneath, all the more reason to use that, no? This structure just enforce that only one sheet can be active at a time at a type-level, which is what the two sheet design couldn’t.

In any case, no, I don’t know how to do it with two sheets. The outer modifier overrides the inner ones.

---

<div class="post-metadata">

**Author:** ![DevAndArtist](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/devandartist/32/287_2.png) [@DevAndArtist](https://forums.swift.org/u/DevAndArtist)\
**Post date:** [April 11, 2020, 3:31pm UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267/7 "2020-04-11T15:31:55Z")

</div>

Check out my answer on stackoverflow how to 'kinda' support multiple modals.

> <https://stackoverflow.com/questions/57103800/swiftui-support-multiple-modals/57873317#57873317>

---

<div class="post-metadata">

**Author:** ![ilyapuchka](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ilyapuchka/32/3327_2.png) [@ilyapuchka](https://forums.swift.org/u/ilyapuchka)\
**Post date:** [April 11, 2020, 4:23pm UTC](https://forums.swift.org/t/multiple-sheet-view-modifiers-on-the-same-view/35267/8 "2020-04-11T16:23:02Z")

</div>

Ended up with the same API myself, just with ZStack instead of background, using a background is a nice way 👍 Still wondering though why it behaves like that out of the box, specifically creating a view and discarding it right away without presenting.
