SwiftUI dismiss modal

前端 未结 13 2201
闹比i
闹比i 2020-11-29 23:23

Since SwiftUI is declarative there is no dismiss methode. How can is add a dismiss/close button to the DetailView?



        
13条回答
  •  情书的邮戳
    2020-11-30 00:07

    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: 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")
            }
        }
    }
    

提交回复
热议问题