如何减小Navigation Bar高度?旧方案失效求最新可用实现方法
早期Swift3版本流传的直接在控制器生命周期回调中修改导航栏frame的方案,在iOS11及之后的系统版本中,会被系统基于安全区的自动布局逻辑强制覆盖重置,目前稳定可生效的实现方式如下:
- 核心实现逻辑
从系统尺寸计算流程层面入手,自定义UINavigationBar子类,重写高度计算逻辑,从根源上避免自定义高度被系统重置。具体代码示例:class AdjustedHeightNavigationBar: UINavigationBar { // 替换为业务需要的导航栏内容区高度(不含顶部安全区/状态栏高度) private let customBarHeight: CGFloat = 64 // 适配手动布局流程下的frame更新 override var frame: CGRect { didSet { var targetFrame = frame let topSafeHeight = UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0 targetFrame.size.height = customBarHeight + topSafeHeight frame = targetFrame } } // 适配Auto Layout触发的尺寸计算流程 override func sizeThatFits(_ size: CGSize) -> CGSize { var calculatedSize = super.sizeThatFits(size) let topSafeHeight = UIApplication.shared.windows.first?.safeAreaInsets.top ?? 0 calculatedSize.height = customBarHeight + topSafeHeight return calculatedSize } } - 方案落地注意事项
- 不要在控制器的
viewDidLayoutSubviews等布局回调中手动修改导航栏frame,所有高度计算逻辑统一封装在自定义子类内部,避免触发系统的布局校验机制导致高度回弹到系统默认值 - 界面搭建方式为Storyboard/Xib时,需要将对应UINavigationBar组件的类属性绑定为上述自定义导航栏子类;代码方式初始化UINavigationController时,可直接传入自定义导航栏实例完成集成
- iOS15及以上版本需要额外配置导航栏的
standardAppearance和scrollEdgeAppearance,保证页面滚动到边缘位置时,导航栏的背景渲染符合预期,不会因高度调整出现显示错位
- 不要在控制器的
内容的提问来源于stack exchange,提问作者safetotry
相关产品推荐
相关产品推荐

