如何修改UINavigationBar高度及导航栏Item的尺寸与位置?
解决方案
一、自定义导航栏高度为74
直接修改UINavigationBar的frame会被系统布局约束覆盖,必须通过自定义导航栏子类实现:
- 创建自定义
UINavigationBar子类:
class CustomNavigationBar: UINavigationBar { override func sizeThatFits(_ size: CGSize) -> CGSize { // 返回自定义高度74,宽度适配屏幕 return CGSize(width: UIScreen.main.bounds.width, height: 74) } override func layoutSubviews() { super.layoutSubviews() // 确保导航栏背景视图高度匹配自定义高度 self.subviews.forEach { subview in if NSStringFromClass(subview.classForCoder).contains("BarBackground") { subview.frame = self.bounds } } } }
- 创建
UINavigationController时指定自定义导航栏类:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { if let windowScene = (scene as? UIWindowScene) { let window = UIWindow(windowScene: windowScene) // 使用自定义导航栏初始化导航控制器 let navigationController = UINavigationController(navigationBarClass: CustomNavigationBar.self, toolbarClass: nil) let viewController = ViewController() navigationController.viewControllers = [viewController] window.rootViewController = navigationController self.window = window window.makeKeyAndVisible() } }
二、设置导航项为50x50,上下间距12
之前的代码直接设置frame和setBackgroundVerticalPositionAdjustment无效,因为系统会自动调整UIBarButtonItem布局。改用AutoLayout约束按钮尺寸,结合自定义导航栏高度自动实现上下间距:
修改ViewController代码(建议在viewDidLoad中执行):
override func viewDidLoad() { super.viewDidLoad() self.navigationController?.navigationBar.backgroundColor = .gray navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil) let menuBtn = UIButton(type: .custom) menuBtn.setImage(UIImage(named:"mute"), for: .normal) // 关闭自动约束转换,启用AutoLayout menuBtn.translatesAutoresizingMaskIntoConstraints = false // 固定按钮尺寸为50x50 NSLayoutConstraint.activate([ menuBtn.widthAnchor.constraint(equalToConstant: 50), menuBtn.heightAnchor.constraint(equalToConstant: 50) ]) let menuBarItem = UIBarButtonItem(customView: menuBtn) self.navigationItem.rightBarButtonItem = menuBarItem }
原理说明
自定义导航栏高度为74后,内部的UIBarButtonItem会自动居中布局。按钮高度50,上下剩余空间74-50=24,平均分配后上下间距各12,正好符合需求。
额外注意事项
- 避免在
viewDidAppear中修改导航栏布局,此时视图已完成布局,系统可能覆盖你的修改,建议在viewDidLoad或导航控制器初始化阶段配置。 - iOS 13+导航栏布局依赖AutoLayout,自定义导航栏时需确保
layoutSubviews中的调整适配系统视图结构。
内容的提问来源于stack exchange,提问作者user1342352532
相关产品推荐
相关产品推荐

