Search code examples
swiftuixcode11

Using SwiftUI, we installed a Button in the List. Why does the modal disappear when I tap the button to display the modal and then close it again?


I am now learning to create a sample code for SwiftUI using the official version of Xcode11. I wrote a simple code to show and hide modal. This code adds a button to the list and displays a modal. Strangely, however, the modal no longer appears when the button is tapped again after closing.

Is there a reason for this or any solution?

Occurs when there is a button in the list, but if you delete only the list from the code, the modal can be displayed as many times as you like.

This is the code that causes the bug.

struct ContentView: View {
  @State var show_modal = false
  var body: some View {
    List {
      Button(action: {
        print("Button Pushed")
        self.show_modal = true
      }) {
        Text("Show Modal")
      }.sheet(isPresented: self.$show_modal, onDismiss: {
        print("dismiss")
      }) {
        ModalView()
      }
    }
  }
}

This is a code that does not cause a bug.

struct ContentView: View {
  @State var show_modal = false
  var body: some View {
      Button(action: {
        print("Button Pushed")
        self.show_modal = true
      }) {
        Text("Show Modal")
      }.sheet(isPresented: self.$show_modal, onDismiss: {
        print("dismiss")
      }) {
        ModalView()
      }
  }
}

The only difference is whether or not there is a List.

The ModalView code is below.

struct ModalView: View {
    // 1. Add the environment variable
    @Environment(\.presentationMode) var presentationMode

    var body: some View {
        // 2. Embed Text in a VStack
        VStack {
            // 3. Add a button with the following action
            Button(action: {
                print("dismisses form")
                self.presentationMode.wrappedValue.dismiss()
            }) {
                Text("Dismiss")
            }.padding(.bottom, 50)
            Text("This is a modal")
        }
    }
}

When breakpoint is set, print ("Button Pushed") is called every time, but ModalView of .sheet is not called, and naturally the body of ModalView class is not called.


Solution

  • I think the issue is that your .sheet is not on the List itself but on the Button in your code that causes the bug.

    Try this instead:

    struct ContentView: View {
        @State var show_modal = false
        var body: some View {
            List {
                Button(action: {
                    print("Button Pushed")
                    self.show_modal = true
                }) {
                    Text("Show Modal")
                }
            }.sheet(isPresented: self.$show_modal, onDismiss: {
                print("dismiss")
            }) {
                ModalView()
            }
        }
    }