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

Posted

技术标签:

【中文标题】如何在 iOS 15 及更早版本上支持程序化视图关闭【英文标题】:How to support programmatic view dismiss on iOS 15 and earlier versions 【发布时间】:2021-07-30 10:05:10 【问题描述】:

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

@Environment(\.presentationMode) var presentationMode

然后调用self.presentationMode.wrappedValue.dismiss() 关闭视图。

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

@Environment(\.dismiss) var dismiss

我们可以使用dismiss() 直接调用它来达到同样的效果。

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

if #available(iOS 15, *) 
    self.dismiss()
 else 
    self.presentationMode.wrappedValue.dismiss()

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

if #available(iOS 15, *) 
    @Environment(\.dismiss) var dismiss
 else 
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

编辑:

显然使用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)
        )
    

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

【问题讨论】:

我建议您仅针对 ios 15 并使用新方法,或者如果您支持旧版本,请坚持使用已弃用的方法。它仍然可以工作。 正如我在您的问题中看到的,您的代码中将有一个@Environment!鄙视观点,对吧?为什么不直接使用和使用原始值呢?忘记dismisspresentationMode @Paulw11 我已经在 iOS 14 上拥有用户,因此目前仅针对 iOS 15 不是一个选项。已弃用的方法不适用于最新的 iOS/Xcode Beta 4。 @Paulw11 我很抱歉。它确实有效。我在导航视图中有一个 TabView,在这种情况下,不幸的是它不起作用。 @mota:只使用dismiss而不提及真正的Binding似乎很酷!但是你为 SwiftUI 或你的项目做了很多工作来找出你在说什么。 【参考方案1】:

你可以用这个,对我很有帮助;

@Environment(.dismiss) var 关闭

这是来源,here

【讨论】:

【参考方案2】:

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

//presentationMode.wrappedValue.dismiss()
   
    if var topController = UIApplication.shared.windows.first!.rootViewController 
        while let presentedViewController = topController.presentedViewController 
            topController = presentedViewController
        
        topController.dismiss(animated: true)
    

【讨论】:

谢谢,但我不确定你会如何在 SwiftUI 中使用它。你能解释一下吗?

以上是关于如何在 iOS 15 及更早版本上支持程序化视图关闭的主要内容,如果未能解决你的问题,请参考以下文章

TestFlight 是不是支持 ios7 及更早版本?

ios:文本在 iPhone 5S 及更早版本(4 英寸及更小的设备)上无法正确换行

在具有部署目标 iOS 7.0 及更早版本的扩展包含应用程序中使用嵌入式框架

UINavigationBar 在 iOS8 及更早版本中消失

706版本打不开。本服务器支持662及更早版本。不支持降级路径

数据库无法打开,因为它是版本 706。此服务器支持版本 655 及更早版本。不支持降级路径