使用NavigationLink在SwiftUI视图间传值时NavigationView嵌套UI异常如何解决
问题原因
你猜测的完全正确,这个UI异常就是三个视图都单独添加了NavigationView导致的嵌套问题。
SwiftUI的NavigationView是导航栈的根容器,仅需要在整个导航流的入口视图(也就是你的ContentView)声明一次即可,所有后续跳转进入的子视图都会自动共享这个导航栈的上下文。你在SecondView、ThirdView里额外新增的NavigationView,相当于在现有导航栈里又嵌套了独立的新导航栈,自然就会出现多层导航栏叠加、返回按钮错位的异常效果,和你截图里的双重导航条表现完全吻合。
另外你的SecondView还存在语法隐患:body内直接并列了Text和NavigationView两个根视图,会隐式生成TupleView导致布局不符合预期,需要把所有内容放到同一个布局容器里。
修复后的代码
ContentView(无需改动,保留根NavigationView即可)
struct ContentView: View { var body: some View { NavigationView { NavigationLink(destination: SecondView(message: "Hello from ContentView")) { Text("Go to Second View") } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
SecondView(删除多余NavigationView,统一内容容器)
struct SecondView: View { var message: String var body: some View { VStack(spacing: 30) { Text("\(message)") NavigationLink(destination: ThirdView(message: self.message)) { Text("Go to Third View") } } // 直接用修饰符自定义当前页导航栏即可,无需新增导航容器 .navigationTitle("第二页") } } struct SecondView_Previews: PreviewProvider { static var previews: some View { // 预览需要导航栏效果时仅在预览层套NavigationView,不影响实际运行逻辑 NavigationView { SecondView(message: String()) } } }
ThirdView(删除多余NavigationView)
struct ThirdView: View { var message: String var body: some View { Text("\(message)") .navigationTitle("第三页") } } struct ThirdView_Previews: PreviewProvider { static var previews: some View { NavigationView { ThirdView(message: String()) } } }
补充提示
如果你的项目最低适配iOS 16及以上版本,更推荐使用官方替代方案NavigationStack替换已经废弃的NavigationView,使用逻辑一致,仅需在根视图声明一次导航容器即可。
内容的提问来源于stack exchange,提问作者JS_is_awesome18
相关产品推荐
相关产品推荐

