SwiftUI 工作表在第一次呈现时被关闭

Posted

技术标签:

【中文标题】SwiftUI 工作表在第一次呈现时被关闭【英文标题】:SwiftUI sheet gets dismissed the first time it is presented 【发布时间】:2020-11-08 19:47:22 【问题描述】:

这个错误快把我逼疯了。有时(大多数情况下)呈现的工作表在打开时第一次被关闭。这仅在设备上发生,并且仅在应用程序首次启动时发生。以下是在运行 ios 14.1 的 iPhone 11 上使用 Xcode 12.1 构建的效果(也可以在运行 iOS 14.0.1 的 iPhone 7 Plus 上重现):

视频中的步骤:

    我打开应用程序 快速导航到详细信息视图 打开工作表 Red Sheed 被系统解散??? 我再次打开工作表,它仍按预期显示在屏幕上。

这是 SwitUI App 项目(使用 UIKIt App Delegate)和部署 iOS 14。代码:

struct ContentView: View 
   
    var body: some View  
        NavigationView 
            NavigationLink(destination: DetailsView()) 
                Text("Open Details View")
            
        
        .navigationViewStyle(StackNavigationViewStyle())
    


struct DetailsView: View 
   
    @State var sheetIsPresented: Bool = false
 
    var body: some View 
        VStack 
            Button("Open") 
                sheetIsPresented.toggle()
            
        .sheet(isPresented: $sheetIsPresented, content: 
            SheetView()
        )
    


struct SheetView: View 
   
    var body: some View 
        Color.red
    

我可以通过删除行 .navigationViewStyle(StackNavigationViewStyle()) 来解决这个问题,但我的项目中需要 StackNavigationViewStyle。任何帮助将不胜感激。

更新:Apple 论坛上有一个类似的post,其工作表视图随机出现异常。 我发现的一种解决方案是将工作表移动到 NavigationLink 之外的根视图(在我的示例中为 ContentView),但这不是理想的解决方案。

【问题讨论】:

我在物理设备上试过没问题!在 SE2 上测试 @Omid 谢谢。您能否多次尝试并快速完成所有操作(导航)?每次尝试后,请强制关闭应用 我尽我所能,发送到后台,然后返回到前台,向上,向下滑动,也可以多次打开,没问题!你试过干净的设备吗?过去发生过几次,旧项目崩溃对设备产生了一些影响 在物理设备上或使用 Xcode 版本 12.1 (12A7403) 的模拟器上没有问题 在 iPhone 7 Plus (iOS 14.0.1) 上测试过,同样的问题。 【参考方案1】:

我在应用中遇到了同样的问题。经过大量研究,我发现将变量设为观察对象解决了 SwiftUI 1 中的问题,并且似乎在 SwiftUI 2 中。我确实记得这是实际设备上的间歇性问题,但它总是发生在模拟器中。我希望我能记住为什么,也许当工作表出现时它会重置绑定变量?但是这段代码解决了这个问题:

import SwiftUI
import Combine

struct ContentView: View 
    var body: some View 
        NavigationView 
            NavigationLink(destination: DetailsView()) 
                Text("Open Details View")
            
        
        .navigationViewStyle(StackNavigationViewStyle())
    


struct DetailsView: View 
   
    @ObservedObject var sheetIsPresented = SheetIsPresented.shared
    
    var body: some View 
        VStack 
            Button("Open") 
                sheetIsPresented.value.toggle()
            
        .sheet(isPresented: $sheetIsPresented.value, content: 
            SheetView()
        )
    


struct SheetView: View 
   
    var body: some View 
        Color.red
    


final class SheetIsPresented: NSObject, ObservableObject 
    let objectWillChange = PassthroughSubject<Void, Never>()
    
    static let shared = SheetIsPresented()
    
    @Published var value: Bool = false 
        willSet 
            objectWillChange.send()
        
    
    



struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ContentView()
    

在 Xcode 12.1、iOS 14.1 模拟器上测试。

【讨论】:

以上是关于SwiftUI 工作表在第一次呈现时被关闭的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI 工作表在首次出现时不会访问状态变量的最新值

SwiftUI 模式表在关闭后重新打开

SwiftUI:为 .sheet(_: onDismiss:) 重置状态

SwiftUI onTapGesture 仅调用一次

Swift:UITextField 在第一次被点击时被立即关闭

如何将关闭按钮从 swiftui 视图的主结构(由 uihostingviewcontroller 呈现)分离到它自己的结构?