SwiftUI中同时使用两种navigationDestination导致导航异常问题咨询
问题分析与解决方案
为什么会出现这个异常?
核心原因是navigationDestination(isPresented:)的双向绑定机制:
- 当你通过
isPresented将「pushed in by isPresented」页面推入栈后,点击页面内的NavigationLink(value:)推送蓝色页面时,SwiftUI会自动把isPresented重置为false——因为此时isPresented绑定的目标页面已不再是导航栈的顶部视图。 - 一旦
isPresented变为false,navigationDestination(isPresented:)会直接将对应的「pushed in by isPresented」页面从栈中移除,连带它上方的蓝色页面也会被一并弹出,最终出现你看到的蓝色页面闪过后,原页面回到栈顶的异常。
简单来说,isPresented绑定的页面的存在完全依赖于这个布尔值的状态,任何导致该页面脱离栈顶的操作都会触发状态重置,进而导致页面被移除。
同时使用两种navigationDestination是否合理?
合理,但要注意使用场景和嵌套限制:
navigationDestination(isPresented:)适合简单的、不需要传递数据的单页面跳转(比如弹窗式的页面),核心是状态驱动。.navigationDestination(for:)适合需要传递数据、多页面层级的导航场景,核心是数据驱动,也是SwiftUI推荐的导航方式。
但绝对不要在isPresented绑定的目标页面中嵌套基于值的NavigationLink,这会触发isPresented的自动重置,导致栈异常。
修复方案
改用全数据驱动的导航方式替代isPresented绑定,避免状态冲突:
import SwiftUI struct TestNavView: View { @State private var activeRoute: String? var body: some View { NavigationStack{ VStack{ Button { activeRoute = "presentedPage" } label: { Text("navigate by value") } } .navigationDestination(for: String.self) { route in switch route { case "presentedPage": VStack{ Text("pushed in by value") NavigationLink(value: "colorPage") { Text("show color view by NavigationLink" ) } } case "colorPage": Color.blue default: EmptyView() } } } } } struct TestNavView_Previews: PreviewProvider { static var previews: some View { TestNavView() } }
这种方式通过统一的路由值管理导航,所有页面跳转都基于数据传递,不会出现状态冲突的问题,也更符合SwiftUI导航的设计理念。
内容的提问来源于stack exchange,提问作者Rufus
相关产品推荐
相关产品推荐

