SwiftUI dismiss model

Since SwiftUI is declarative there is no `dismiss` methode.

How can is add a dismiss/close button to the `

DetailView
`?


struct DetailView: View {
  var body: some View {
  Text("Detail")
  }
}

struct ContentView : View {
  var body: some View {
  PresentationButton(Text("Click to show"), destination: DetailView())
  }
}

Since `PresentationButton` is easy to use but hiding the state wich is undermining the predictive character of `SwiftUI` I have implemented it with an accessible `Binding`.


public struct BindedPresentationButton<label, destination="">: View where Label: View, Destination: View {
    /// The state of the modal presentation, either `visibile` or `off`.
    private var showModal: Binding


    /// A `View` to use as the label of the button.
    public var label: Label


    /// A `View` to present.
    public var destination: Destination


    /// A closure to be invoked when the button is tapped.
    public var onTrigger: (() -> Void)?


    public init(
        showModal: Binding,
        label: Label,
        destination: Destination,
        onTrigger: (() -> Void)? = nil
    ) {
        self.showModal = showModal
        self.label = label
        self.destination = destination
        self.onTrigger = onTrigger
    }


    public var body: some View {
        Button(action: toggleModal) {
            label
        }
        .presentation(
            !showModal.value ? nil :
                Modal(
                    destination, onDismiss: {
                        self.toggleModal()
                    }
                )
        )
    }


    private func toggleModal() {
        showModal.value.toggle()
        onTrigger?()
    }
}



This is how it is used:


struct DetailView: View {
    @Binding var showModal: Bool


    var body: some View {
        Group {
            Text("Detail")
            Button(action: {
                self.showModal = false
            }) {
                Text("Dismiss")
            }
        }
    }
}


struct ContentView: View {
    @State var showModal = false


    var body: some View {
        BindedPresentationButton(
            showModal: $showModal,
            label: Text("Show"),
            destination: DetailView(showModal: $showModal)
        ) {
            print("dismissed")
        }
    }
}

Use `isPresented` environment variable.


struct DetailView : View {
    
    @Environment(\.isPresented) var isPresented: Binding<Bool>?
    
    var body: some View {
        VStack {
            Rectangle()
                .fill(Color.orange)
                .edgesIgnoringSafeArea(.top)
                .frame(height: 300)
            Text("Hello World")
            Button(action: {
                self.isPresented?.value = false
            }) {
                Text("Pop")
            }
            Spacer()
        }
        .edgesIgnoringSafeArea(.top)
    }
}

Thank you for the hint with Environment.


How to access `isPresented` for outside like in my example?

Thank you
fill is not working with Rectangle() but its working with RoundedRectangle(cornerRadius: 20) in SwiftUI

                    RoundedRectangle(cornerRadius: 20)
                        .fill(Color.blue)
                        .frame(height: 3.0)

This is no longer working for me. Something changed with Xcode 11 beta 3 and remains in beta 4. The value of

isPresented
is nil prior to setting it to false and remains nil afterwards.


Any ideas?

SwiftUI dismiss model
 
 
Q