iOS 17中SwiftUI Toolbar内NavigationLink仅显示图标不显示文本问题
问题原因
iOS 17 对导航栏内的 NavigationLink 组件做了视觉行为调整:当 NavigationLink 被放置在导航栏的 ToolbarItem 中时,系统会默认应用紧凑的导航按钮样式,自动隐藏文本内容,仅保留图标类元素。而iOS 17之前的版本没有这个默认样式限制,因此你的代码能正常显示文本+图标组合。
同时需要注意,NavigationView 在iOS 16之后已被官方标记为过时组件,推荐使用 NavigationStack 替代,后续系统版本可能会逐步移除对 NavigationView 的支持。
修复方案
方案1:保留NavigationView,修改按钮样式
给 NavigationLink 添加 .buttonStyle(.plain) 修饰符,取消系统默认的紧凑样式,让自定义的 HStack 完整显示:
NavigationView { ZStack(alignment: .bottomTrailing) { // my body } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { NavigationLink(destination: StreakView(dayStreak: viewModel.dayStreak)) { HStack { Text("\(viewModel.dayStreak)") Image(systemName: "flame.fill") } } .buttonStyle(.plain) // 添加该行取消默认紧凑样式 } } }
方案2:改用NavigationStack(官方推荐)
使用iOS 16+推出的 NavigationStack 结合 navigationDestination 实现导航,这种方式更符合苹果最新的导航架构设计:
- 首先在视图中声明导航路径管理对象:
@State private var navigationPath = NavigationPath()
- 替换原有的
NavigationView为NavigationStack,并用Button触发导航,配合navigationDestination指定目标页面:
NavigationStack(path: $navigationPath) { ZStack(alignment: .bottomTrailing) { // my body } .toolbar { ToolbarItem(placement: .navigationBarTrailing) { Button { navigationPath.append("streak") // 将导航标识加入路径 } label: { HStack { Text("\(viewModel.dayStreak)") Image(systemName: "flame.fill") } } } } .navigationDestination(for: String.self) { path in if path == "streak" { StreakView(dayStreak: viewModel.dayStreak) } } }
你可以根据实际需求选择方案:如果只是临时兼容iOS 17,方案1快速有效;如果需要长期维护应用,方案2更符合苹果的技术演进方向。
内容的提问来源于stack exchange,提问作者Clément
相关产品推荐
相关产品推荐

