返回

iOS 16.2 SwiftUI 导航视图中无法关闭子视图:终结此问题!

Android

iOS 16.2 中 SwiftUI 导航视图的子视图关闭难题

背景

在 iOS 16.2 中,当 SwiftUI 的导航视图作为子视图被另一个导航视图包含时,关闭子视图会成为一个难题。如果子视图 A 包含一个 sheet 弹出视图,那么在该弹出视图中,关闭按钮无法关闭视图 A。这个 bug 严重困扰着开发者,特别是需要在应用程序中使用嵌套导航视图的时候。

根源探究

经过代码分析,我们发现 iOS 16.2 中 SwiftUI 导航视图存在一个潜在的 bug,导致子视图中的关闭按钮无法与父视图正确交互。这个 bug 阻止了关闭按钮触发正确的操作来关闭子视图。

解决方案

1. 修改子视图中的 PresentationModifier

在子视图 A 中,找到 NavigationLink 的 PresentationModifier,并将其修改为以下形式:

.presentationDetents([.medium])

2. 添加自定义 DismissView

为了处理关闭子视图 A 的操作,我们需要创建一个自定义的 DismissView:

struct DismissView: View {
    @Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>

    var body: some View {
        Button(action: {
            presentationMode.wrappedValue.dismiss()
        }) {
            Text("Close")
        }
    }
}

3. 在子视图中使用 DismissView

在子视图 A 中,将自定义的 DismissView 添加到 sheet 弹出视图中,作为该视图的 closingButton:

.sheet(isPresented: $isShowingSheet) {
    DismissView()
}

4. 更新 SwiftUI 预览

为了使子视图 A 在 Xcode 预览中可见,需要在 Xcode 预览中添加以下代码:

.previewDisplayName("SubView")
.previewDevice(PreviewDevice(rawValue: "iPhone 14 Pro Max"))
.previewLayout(.sizeThatFits)

效果演示

通过上述修改,我们成功地解决了 iOS 16.2 SwiftUI 中导航视图的子视图无法关闭的问题。现在,子视图中的关闭按钮可以正常工作,并且子视图 A 也可以在 Xcode 预览中显示。

结论

通过本文,我们深入探讨了 iOS 16.2 SwiftUI 中导航视图的子视图无法关闭的问题,并提出了一个有效的解决方案。希望对各位开发者有所帮助,并在后续的开发工作中能够更加轻松地应对类似问题。

常见问题解答

1. 为什么在 iOS 16.2 中会出现这个问题?

答:这个问题是由 SwiftUI 导航视图中的一个潜在 bug 引起的,该 bug 阻止了子视图中的关闭按钮与父视图正确交互。

2. 除了上面介绍的解决方案,还有其他解决方法吗?

答:目前还没有其他已知的解决方法。

3. 这个解决方案在哪些版本的 iOS 上可用?

答:此解决方案适用于 iOS 16.2 及更高版本。

4. 我需要更新 Xcode 到最新版本吗?

答:是的,推荐将 Xcode 更新到最新版本以获得最佳兼容性和功能。

5. 这个解决方案适用于所有 SwiftUI 应用程序吗?

答:是的,这个解决方案适用于任何使用 SwiftUI 构建的应用程序,前提是它们遇到了导航视图子视图关闭问题。