Skip to content

Instantly share code, notes, and snippets.

@mbrandonw
Last active September 18, 2021 13:02
Show Gist options
  • Save mbrandonw/82ece7c62afb370a875fd1db2f9a236e to your computer and use it in GitHub Desktop.
Save mbrandonw/82ece7c62afb370a875fd1db2f9a236e to your computer and use it in GitHub Desktop.

FB8379503

Sheet modifier on nested view does not work

If a .sheet modifier is used on a child view while the parent view is also using a .sheet modifier, then the child view’s sheet will never appear:

struct ContentView: View {
  @State var isPresented1 = false
  @State var isPresented2 = false

  var body: some View {
    VStack {
      Button("One") { self.isPresented1 = true }
        .sheet(isPresented: self.$isPresented1) {
          Text("πŸ›‘ This will never show... πŸ›‘")
        }

      Button("Two") { self.isPresented2 = true }
    }
    .sheet(isPresented: self.$isPresented2) {
      Text("Two presented")
    }
  }
}

This can be really problematic when you extract child views to their own structs:

struct ContentView: View {
  @State var isPresented = false

  var body: some View {
    VStack {
      ChildView()

      Button("Two") { self.isPresented2 = true }
    }
    .sheet(isPresented: self.$isPresented2) {
      Text("Two presented")
    }
  }
}

struct ChildView: View {
  @State var isPresented = false
  
  var body: some View {
    Button("One") { self.isPresented1 = true }
      .sheet(isPresented: self.$isPresented1) {
        Text("πŸ›‘ This will never show... πŸ›‘")
      }
  }
}

This is a huge gotcha because the child view must know that none of its parent views use the .sheet modifier in order to be certain that its .sheet will work.

FB8379518

Alert modifier on nested view does not work

If a .alert modifier is used on a child view while the parent view is also using a .alert modifier, then the child view’s alert will never appear:

struct ContentView: View {
  @State var isPresented1 = false
  @State var isPresented2 = false

  var body: some View {
    VStack {
      Button("One") { self.isPresented1 = true }
        .alert(isPresented: self.$isPresented1) {
          Alert(title: Text("πŸ›‘ This will never show... πŸ›‘"))
        }

      Button("Two") { self.isPresented2 = true }
    }
    .alert(isPresented: self.$isPresented2) {
      Alert(title: Text("Two presented"))
    }
  }
}

This can be really problematic when you extract child views to their own structs:

struct ContentView: View {
  @State var isPresented = false

  var body: some View {
    VStack {
      ChildView()

      Button("Two") { self.isPresented2 = true }
    }
    .alert(isPresented: self.$isPresented) {
      Alert(title: Text("Two presented"))
    }
  }
}

struct ChildView: View {
  @State var isPresented = false
  
  var body: some View {
    Button("One") { self.isPresented1 = true }
      .alert(isPresented: self.$isPresented) {
        Alert(title: Text("πŸ›‘ This will never show... πŸ›‘"))
      }
  }
}

This is a huge gotcha because the child view must know that none of its parent views use the .alert modifier in order to be certain that its .alert will work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment