SwiftUI的NavigationLink不显示视图,仅设备旋转后才正常如何解决?
问题根因
你遇到的是iPadOS/macOS下NavigationView默认DoubleColumnNavigationViewStyle的已知渲染bug:初始加载时系统未正确识别绑定的selection值,无法触发详情栏的视图渲染,只有触发界面重绘(旋转屏幕、点击返回)后才会正常加载。
不推荐主动触发设备旋转
主动修改设备方向需要申请特殊权限,还会打乱用户的屏幕方向使用习惯,体验极差,完全不需要通过这种方式规避问题。
可行解决方案
方案1:延迟赋值selection
不要在初始化时直接给selection赋值,改为视图加载后异步赋值,避开初始渲染的时序问题:
struct MainView: View { // 初始赋值为nil @State var selection: Int? = nil var body: some View { NavigationView { List { NavigationLink("First View", tag: 1, selection: $selection){ FirstView(viewNum: $selection)} NavigationLink("Second View", tag: 2, selection: $selection){ Text("View 2").padding(20) Button { selection = 1 } label: { Text("Go to first view") } } } } .onAppear { // 异步延迟赋值,等待NavigationView初始渲染完成 DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) { selection = 1 } } } }
方案2:强制触发NavigationView重绘
给NavigationView绑定唯一标识,视图加载时刷新标识强制重绘,解决初始渲染遗漏的问题:
struct MainView: View { @State var selection: Int? = 1 // 新增唯一标识变量 @State private var navId = UUID() var body: some View { NavigationView { List { NavigationLink("First View", tag: 1, selection: $selection){ FirstView(viewNum: $selection)} NavigationLink("Second View", tag: 2, selection: $selection){ Text("View 2").padding(20) Button { selection = 1 } label: { Text("Go to first view") } } } } // 绑定标识 .id(navId) .onAppear { // 刷新标识触发重绘 navId = UUID() } } }
方案3:显式声明默认详情视图
DoubleColumnNavigationViewStyle支持显式指定默认的详情栏视图,直接补全声明即可解决初始空白问题:
struct MainView: View { @State var selection: Int? = 1 var body: some View { // 显式声明列表和详情两部分内容 NavigationView { List { NavigationLink("First View", tag: 1, selection: $selection){ FirstView(viewNum: $selection)} NavigationLink("Second View", tag: 2, selection: $selection){ Text("View 2").padding(20) Button { selection = 1 } label: { Text("Go to first view") } } } // 显式指定默认详情视图 detail: { if let selection = selection { switch selection { case 1: FirstView(viewNum: $selection) case 2: Text("View 2").padding(20) Button { selection = 1 } label: { Text("Go to first view") } default: EmptyView() } } else { FirstView(viewNum: $selection) } } } } }
以上三个方案都不需要修改NavigationView的样式,可保留你需要的双栏布局行为,任选其一即可解决初始空白问题。
内容的提问来源于stack exchange,提问作者JWA
相关产品推荐
相关产品推荐

