如何在 iOS 15 及更早版本上支持编程视图关闭

Mot*_*sim 15 ios swift swiftui

在 iOS 14 及更早版本上,我们导入presentationMode环境变量:

@Environment(\.presentationMode) var presentationMode
Run Code Online (Sandbox Code Playgroud)

然后打电话self.presentationMode.wrappedValue.dismiss()驳回视图。

这在 iOS 15 上已被弃用,并dismiss引入了一个新的环境变量 :

@Environment(\.dismiss) var dismiss
Run Code Online (Sandbox Code Playgroud)

我们可以直接调用 usingdismiss()来实现相同的效果。

我知道我们可以执行以下操作来调用适当的解雇函数并支持所有版本:

if #available(iOS 15, *) {
    self.dismiss()
} else {
    self.presentationMode.wrappedValue.dismiss()
}
Run Code Online (Sandbox Code Playgroud)

但是如何导入/定义正确的环境变量呢?因为尝试这不起作用:

if #available(iOS 15, *) {
    @Environment(\.dismiss) var dismiss
} else {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
}
Run Code Online (Sandbox Code Playgroud)

编辑:

显然,presentationMode在 iOS 15 Beta 4 上,使用关闭导航堆栈中的视图仍然有效。除非 NavigationView 中有 TabView:

struct ContentView: View {
    var body: some View {
        NavigationView {
            TabView {
                NavigationLink(destination: ChildView()) {
                    Text("View Child")
                }
            }
        }
    }
}

struct ChildView: View {
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        Button(action: {
            print("Popping...")
            self.presentationMode.wrappedValue.dismiss()
        }, label: {
            Text("POP")
                .font(.headline)
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

presentatinMode在这种情况下不起作用。

shb*_*bli 10

为了支持解雇和 iOS 14 将此扩展添加到您的环境值中

@available(iOS 14.0, *)
extension EnvironmentValues {
    var dismiss: () -> Void {
        { presentationMode.wrappedValue.dismiss() }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ben*_*n10 2

我知道这个苹果还没有修复 SwiftUI 中的错误。到目前为止,我遵循以下方法,它将适用于我的所有版本。可能对您的情况有帮助

//presentationMode.wrappedValue.dismiss()
   
    if var topController = UIApplication.shared.windows.first!.rootViewController {
        while let presentedViewController = topController.presentedViewController {
            topController = presentedViewController
        }
        topController.dismiss(animated: true)
    }
Run Code Online (Sandbox Code Playgroud)