SwiftUI despedir modal
modal-dialog (4)
Dado que SwiftUI es declarativo, no hay un método de
dismiss
.
¿Cómo se puede agregar un botón de cerrar / cerrar en
DetailView
?
struct DetailView: View {
var body: some View {
Text("Detail")
}
}
struct ContentView : View {
var body: some View {
PresentationButton(Text("Click to show"), destination: DetailView())
}
}
Aquí hay una manera de descartar la vista presentada.
struct DetailView: View {
@Binding
var dismissFlag: Bool
var body: some View {
Group {
Text("Detail")
Button(action: {
self.dismissFlag.toggle()
}) {
Text("Dismiss")
}
}
}
}
struct ContentView : View {
@State var dismissFlag = false
var body: some View {
Button(action: {
self.dismissFlag.toggle()
})
{ Text("Show") }
.presentation(!dismissFlag ? nil :
Modal(DetailView(dismissFlag: $dismissFlag)) {
print("dismissed")
})
}
}
Dado que
PresentationButton
es fácil de usar, pero oculta el estado que está socavando el carácter predictivo de
SwiftUI
lo he implementado con un
Binding
accesible.
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<Bool>
/// 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<Bool>,
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?()
}
}
Así es como se usa:
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")
}
}
}
Otra forma de descartar el modal es mediante la variable de entorno isPresented , que es:
Un enlace a un valor booleano que indica si esta instancia es parte de una jerarquía actualmente presentada.
Todo lo que necesita hacer es establecer el valor de esta variable en
false
en su vista modal:
struct DetailView : View {
@Environment(/.isPresented) var isPresented: Binding<Bool>?
var body: some View {
Group {
Text("Detail view")
Button(action: {
self.isPresented?.value = false
}) {
Text("Dismiss")
}
}
}
}
struct ContentView : View {
var body: some View {
PresentationButton(Text("Show modal"), destination: DetailView())
}
}
Puedes implementar esto.
struct view: View {
@Environment(/.isPresented) private var isPresented
private func dismiss() {
isPresented?.value = false
}
}