如何为SwiftUI的NavigationStack设置自定义NavigationBar高度?
由于SwiftUI没有直接提供修改NavigationBar高度的API,结合你的需求(保留.navigationBarTitleDisplayMode(.inline)),可以通过UIKit桥接实现,以下是两种可行方案:
方案一:针对当前视图动态修改导航栏高度
这种方案只会影响当前视图,离开后恢复默认高度,适合局部自定义需求:
NavigationStack{ List{ Section{ // 你的列表内容 } } .listStyle(.plain) .toolbar { ToolbarItem(placement:.topBarLeading){ CustomFeedNav() } ToolbarItem (placement: .navigationBarTrailing) { Button{ }label: { Image(systemName: "arrow.counterclockwise.circle") } } } .navigationBarTitleDisplayMode(.inline) // 保留inline设置 .onAppear { // 获取当前导航控制器(适配iOS13+场景) guard let navController = UIApplication.shared.connectedScenes .compactMap({ $0 as? UIWindowScene }) .first?.windows .first?.rootViewController as? UINavigationController else { return } // 设置自定义高度(示例设为80,可按需调整) navController.navigationBar.frame.size.height = 80 navController.navigationBar.setNeedsLayout() navController.navigationBar.layoutIfNeeded() } .onDisappear { // 恢复默认导航栏高度 guard let navController = UIApplication.shared.connectedScenes .compactMap({ $0 as? UIWindowScene }) .first?.windows .first?.rootViewController as? UINavigationController else { return } navController.navigationBar.frame.size.height = UINavigationBar().frame.height navController.navigationBar.setNeedsLayout() navController.navigationBar.layoutIfNeeded() } }
方案二:通过UINavigationBarAppearance全局自定义(可局部恢复)
这种方案通过设置导航栏外观固定高度,适合需要统一风格的场景:
// 定义自定义导航栏外观的工具方法 func customNavigationBarAppearance(height: CGFloat) -> UINavigationBarAppearance { let appearance = UINavigationBarAppearance() appearance.configureWithOpaqueBackground() appearance.backgroundColor = .systemBackground // 匹配系统背景色 // 创建自定义背景视图撑开高度 let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: height)) backgroundView.backgroundColor = .systemBackground appearance.backgroundView = backgroundView // 保留inline模式的标题样式,可按需调整位置适配新高度 appearance.titleTextAttributes = [ .font: UIFont.preferredFont(forTextStyle: .headline), .foregroundColor: UIColor.label ] appearance.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 10) return appearance } // 在你的视图中应用 NavigationStack{ List{ Section{ // 你的列表内容 } } .listStyle(.plain) .toolbar { ToolbarItem(placement:.topBarLeading){ CustomFeedNav() } ToolbarItem (placement: .navigationBarTrailing) { Button{ }label: { Image(systemName: "arrow.counterclockwise.circle") } } } .navigationBarTitleDisplayMode(.inline) .onAppear { let customAppearance = customNavigationBarAppearance(height: 80) UINavigationBar.appearance().standardAppearance = customAppearance UINavigationBar.appearance().scrollEdgeAppearance = customAppearance } .onDisappear { // 恢复默认导航栏外观 let defaultAppearance = UINavigationBarAppearance() defaultAppearance.configureWithOpaqueBackground() UINavigationBar.appearance().standardAppearance = defaultAppearance UINavigationBar.appearance().scrollEdgeAppearance = defaultAppearance } }
注意事项
- 两种方案均保留
.navigationBarTitleDisplayMode(.inline),不影响原有配置。 - 自定义高度后,可通过给ToolbarItem添加
padding调整位置,确保内容在导航栏中居中对齐。 - 方案一的导航控制器获取方式适配了iOS13+的场景,避免了旧API废弃问题。
内容的提问来源于stack exchange,提问作者helloimbrando
相关产品推荐
相关产品推荐

