iOS17.2下SwiftUI页面切换因导航栏状态变更卡顿无响应问题
问题解决:iOS17下SwiftUI导航跳转卡顿无响应
问题背景
在iPhone14 Pro Max(iOS17.2.1)的SwiftUI开发场景中,从带有NavigationBar的页面跳转至隐藏NavigationBar的页面,滑动返回后再次点击跳转按钮,页面出现卡顿无响应。该问题在iOS16系统中表现正常。
问题原因
- NavigationView兼容性问题:iOS17中
NavigationView已被NavigationStack替代,继续使用旧API易导致导航栈状态异常。 - 自定义手势代理冲突:自定义的
UINavigationController手势代理实现,与iOS17原生导航手势逻辑冲突,破坏了导航交互的正常流程。
修复方案
方案1:替换NavigationView为NavigationStack
使用iOS16+推荐的NavigationStack替代旧的NavigationView,适配系统新特性:
struct TestView : View { var body: some View { NavigationStack { // 替换为NavigationStack ZStack{ NavigationLink { SecondView() } label: { Text("To SecondView") } } .navigationTitle("First page") } } } struct SecondView : View { var body: some View { VStack{ Text("SecondView") } .navigationBarHidden(true) // iOS16+也可使用更灵活的toolbar隐藏方式 //.toolbar(.hidden, for: .navigationBar) } }
方案2:移除自定义UINavigationController扩展
iOS17的NavigationStack已原生支持滑动返回手势,无需额外自定义代理,移除以下代码避免冲突:
// 删除该扩展代码 // extension UINavigationController: UIGestureRecognizerDelegate { // override open func viewDidLoad() { // super.viewDidLoad() // interactivePopGestureRecognizer?.delegate = self // } // // public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { // return viewControllers.count > 1 // } // }
方案3:跨iOS版本兼容写法
若需同时兼容iOS16和iOS17,可使用条件编译:
struct TestView : View { var body: some View { if #available(iOS 16.0, *) { NavigationStack { contentView } } else { NavigationView { contentView } } } private var contentView: some View { ZStack{ NavigationLink { SecondView() } label: { Text("To SecondView") } } .navigationTitle("First page") } } struct SecondView : View { var body: some View { VStack{ Text("SecondView") } .navigationBarHidden(true) } }
验证效果
修复后重复执行跳转-滑动返回操作,页面可正常跳转,手势返回功能正常,无卡顿现象。
内容的提问来源于stack exchange,提问作者Code Porter
相关产品推荐
相关产品推荐

