SwiftUI中关闭Sheet并修改NavigationPath后按钮自动禁用问题
问题场景
这段代码实现了基础的导航+弹窗交互:
- ContentView通过
NavigationStack的导航链接进入Subview - Subview弹出SomeSheet弹窗
- 点击SomeSheet的按钮时,会关闭弹窗并修改
NavigationPath回到ContentView
逻辑执行后能正常返回ContentView,但此时页面内所有按钮都会被自动禁用,测试环境为Xcode 14.0(iOS 16)。
问题原因
这是iOS 16早期版本的SwiftUI已知bug,核心问题是弹窗关闭与导航路径修改的时序冲突。在同一个用户动作中先后调用dismiss()和修改NavigationPath时,SwiftUI的视图状态更新机制出现异常,错误地将ContentView的交互状态标记为禁用。
解决方案
有三种可行的修复方式:
- 方案1:延迟修改导航路径
给导航路径修改操作添加微小延迟,确保弹窗完全关闭后再更新导航状态:Button("Dismiss and go back to ContentView") { dismiss() DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { model.path.removeLast() } } - 方案2:异步等待弹窗状态更新
使用Task配合await Task.yield()等待弹窗关闭的状态更新完成后,再修改导航路径:Button("Dismiss and go back to ContentView") { Task { dismiss() await Task.yield() model.path.removeLast() } } - 方案3:升级开发环境
升级到Xcode 14.1及以上版本(对应iOS 16.1+),苹果在后续版本中修复了NavigationStack与弹窗交互的状态同步问题。
内容的提问来源于stack exchange,提问作者parapote
相关产品推荐
相关产品推荐

