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