NavigationView中navigationBarBackButtonHidden首次运行失效问题
自定义导航栏首次显示异常问题解决
问题描述
设置navigationBarBackButtonHidden(true)以隐藏默认返回按钮、自定义导航工具栏后,首次通过NavigationLink进入第二个页面时,标题异常显示为“Back Button Text”;关闭页面后再次进入,导航栏则恢复正常显示。
首次进入异常效果:
正常显示效果:
该问题在Xcode 15.4(含最新beta补丁)中可复现,代码片段如下:
struct MyNavigationView: View { var body: some View { NavigationView { ScrollView { NavigationLink { SecondScreen(showCloseButton: true) .navigationBarHidden(true) } label: { HStack { Image(systemName: "tortoise.circle.fill") VStack(alignment: .leading, spacing: 0) { Text("SecondScreen") .font(.headline) Text("Touch for Info") .font(.system(size: 10)) } Spacer() } } } .padding(.horizontal) .navigationBarItems( leading: Image(systemName: "trash.circle"), trailing: NavigationLink(destination: { SecondScreen(showCloseButton: false).navigationBarBackButtonHidden(true) }, label: { Image(systemName: "plus.circle") }) ) .navigationTitle("Master View") .navigationBarBackButtonHidden(true) .accentColor(.pink) } } } struct SecondScreen: View { @Environment(\.dismiss) var dismiss var showCloseButton: Bool init(showCloseButton: Bool) { self.showCloseButton = showCloseButton } var body: some View { ZStack(alignment: .topLeading) { Color.pink .ignoresSafeArea() if showCloseButton { VStack { Button { dismiss() } label: { Image(systemName: "xmark.circle") .font(.largeTitle) .foregroundColor(.white) .padding(20) } } } VStack(alignment: .center) { Text("Hello world!").foregroundColor(.white).font(.largeTitle) } .frame(maxWidth: .infinity, maxHeight: .infinity) .toolbar { ToolbarItem(placement: .topBarLeading) { Button(action: { dismiss() }, label: { Image(systemName: "arrowshape.backward.circle") .foregroundColor(.white) Text("Back") .foregroundColor(.white) .fontWeight(.bold) }) } } //.toolbarBackground(.hidden, for: .navigationBar) .navigationBarBackButtonHidden(true) .navigationTitle("Detail Title") } } }
解决方案
NavigationView已被苹果弃用,核心解决方式是将其替换为iOS 16+引入的NavigationStack,并适配新的导航API用法:
修改后的代码示例:
struct MyNavigationView: View { var body: some View { NavigationStack { // 替换为NavigationStack ScrollView { NavigationLink { SecondScreen(showCloseButton: true) } label: { HStack { Image(systemName: "tortoise.circle.fill") VStack(alignment: .leading, spacing: 0) { Text("SecondScreen") .font(.headline) Text("Touch for Info") .font(.system(size: 10)) } Spacer() } } } .padding(.horizontal) .toolbar { // 用toolbar替代navigationBarItems ToolbarItem(placement: .navigationBarLeading) { Image(systemName: "trash.circle") } ToolbarItem(placement: .navigationBarTrailing) { NavigationLink { SecondScreen(showCloseButton: false) .navigationBarBackButtonHidden(true) } label: { Image(systemName: "plus.circle") } } } .navigationTitle("Master View") .navigationBarBackButtonHidden(true) .accentColor(.pink) } } } struct SecondScreen: View { @Environment(\.dismiss) var dismiss var showCloseButton: Bool init(showCloseButton: Bool) { self.showCloseButton = showCloseButton } var body: some View { ZStack(alignment: .topLeading) { Color.pink .ignoresSafeArea() if showCloseButton { VStack { Button { dismiss() } label: { Image(systemName: "xmark.circle") .font(.largeTitle) .foregroundColor(.white) .padding(20) } } } VStack(alignment: .center) { Text("Hello world!").foregroundColor(.white).font(.largeTitle) } .frame(maxWidth: .infinity, maxHeight: .infinity) .toolbar { ToolbarItem(placement: .topBarLeading) { Button(action: { dismiss() }, label: { Image(systemName: "arrowshape.backward.circle") .foregroundColor(.white) Text("Back") .foregroundColor(.white) .fontWeight(.bold) }) } } .navigationBarBackButtonHidden(true) .navigationTitle("Detail Title") } } }
核心修改点:
- 用
NavigationStack替代已弃用的NavigationView - 用
toolbar修饰器替代navigationBarItems,适配新API规范 - 调整
NavigationLink写法,匹配NavigationStack的导航逻辑
替换后即可解决首次进入页面时导航栏显示异常的问题。
内容的提问来源于stack exchange,提问作者rotecodefraktion
相关产品推荐
相关产品推荐

