I have a SwiftUI modal that I would like to either clear the state of or reinitialize. Reinitalizing would be preferred considering the fact that this modal can open other modals that may have some state.
Here is a simple example:
import SwiftUI
struct OtherView: View {
@State var otherViewState: String = ""
var body: some View {
TextField($otherViewState, placeholder: Text("Demo Text Input"))
}
}
struct Demo: View {
@State var showModal: Bool = false
var modal: Modal {
Modal(OtherView(), onDismiss: { self.showModal = false })
}
var body: some View {
Button(action: { self.showModal = true }) {
Text("Toggle Modal")
}
.presentation(self.showModal ? self.modal : nil)
}
}
Regardless of how OtherView is dismissed, I would like to reopen it with its text state cleared, with the requirement that OtherView could open modals itself. Adding a clear
method on the OtherView struct itself is always an option, but I don't find it to be a maintainable one.
Below is a video of the simplified problem:
Update September 11th: This appears to be fixed in iOS 13 GM.
I've been struggling with the same thing and I would like to think that this is a bug that will be resolve by September, I've already filed it on Feedback Assistant, make sure to do the same!
For now though you can just create a new UIHostingController that wraps the SwiftUI View that you want to show modally. I know it looks really hacky but at least it works:
import SwiftUI
struct OtherView: View {
@State var otherViewState: String = ""
var body: some View {
TextField($otherViewState, placeholder: Text("Demo Text Input"))
}
}
struct Demo: View {
var body: some View {
Button("Toggle Modal") {
self.showModal()
}
}
func showModal() {
let window = UIApplication.shared.windows.first
window?.rootViewController?.present(UIHostingController(rootView: OtherView()), animated: true)
}
}
You might want to improve how you get the window, specially if you support multiple windows but I think you get the idea.
You can reinitialize your Modal in .onAppear(). This example works on Beta 3.
import SwiftUI
struct ModalView : View {
@Environment(\.isPresented) var isPresented: Binding<Bool>?
@State var textName: String = ""
var body: some View {
NavigationView {
Form {
Section() {
TextField("Name", text: self.$textName)
.textFieldStyle(.roundedBorder)
}
}
.listStyle(.grouped)
.navigationBarTitle(Text("Add Name"), displayMode: .large)
.navigationBarItems(leading: Button(action:{ self.dismiss() })
{ Text("Cancel") },
trailing: Button(action:{ self.dismiss() })
{ Text("Save") } )
.onAppear(perform: {
self.textName = ""
})
}
}
func dismiss() {
self.isPresented?.value = false
}
}
struct DetailView : View {
var body: some View {
PresentationLink(destination: ModalView())
{ Text("Present") }
}
}
struct ContentView : View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailView())
{ Text("Navigate") }
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With