SwiftUI:清除模态状态或重新初始化

SwiftUI: Clear Modal state or Reinitialize

我有一个 SwiftUI 模态,我想清除它的状态或重新初始化它。考虑到此模态可以打开其他可能具有某些状态的模态这一事实,最好重新初始化。

这是一个简单的例子:

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

不管 OtherView 是如何被关闭的,我都想在清除文本状态的情况下重新打开它,同时要求 OtherView 可以自己打开模式。在 OtherView 结构本身上添加一个 clear 方法始终是一个选项,但我认为它不是一个可维护的方法。

下面是简化问题的视频:

9 月 11 日更新: 这似乎已在 iOS 13 GM 中修复。

我一直在为同样的事情苦苦挣扎,我认为这是一个将在 9 月解决的错误,我已经在反馈助手上提交了它,一定要这样做!

虽然现在您可以创建一个新的 UIHostingController 来包装您想要以模态方式显示的 SwiftUI 视图。我知道它看起来很老套,但至少它有效:

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

您可能想改进获得 window 的方式,特别是如果您支持多个 windows,但我想您明白了。

您可以在.onAppear() 中重新初始化模态框。此示例适用于 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") }
        }
    }
}