iOS 26中UINavigationBar的UIBarButtonItem尺寸与间距适配问题
看起来你在iOS 26上遇到了自定义导航栏按钮的尺寸和间距不兼容的问题,我之前踩过类似的导航栏布局坑,给你几个实用的解决方案:
问题原因分析
先理清楚为什么会出现这个差异:
- iOS 26对
UIBarButtonItem的自定义视图布局逻辑做了调整,直接给自定义视图设置的尺寸约束优先级可能低于导航栏内部的布局约束,导致宽度没被正确应用 - 系统默认的导航栏按钮间距在新版本里增大了,所以你看到横向间隙比iOS 18更宽
解决方案一:给自定义视图套一层容器View(最稳妥的方案)
导航栏对直接作为customView的UIView有默认的布局限制,套一层容器视图可以隔离系统的布局影响,确保你的尺寸约束完全生效。修改后的代码如下:
navigationItem.rightBarButtonItems = views.map { v in // 新增容器视图,隔离系统布局干扰 let containerView = UIView() containerView.addSubview(v) v.translatesAutoresizingMaskIntoConstraints = false // 让目标视图在容器中居中,同时严格控制尺寸 NSLayoutConstraint.activate([ v.centerXAnchor.constraint(equalTo: containerView.centerXAnchor), v.centerYAnchor.constraint(equalTo: containerView.centerYAnchor), v.widthAnchor.constraint(equalToConstant: 12), v.heightAnchor.constraint(equalToConstant: 12) ]) let item = UIBarButtonItem(customView: containerView) if #available(iOS 26.0, *) { item.hidesSharedBackground = true } // 给容器设置合适的点击区域(导航栏按钮默认点击区域是44x44,避免用户点击不灵敏) containerView.widthAnchor.constraint(equalToConstant: 44).isActive = true containerView.heightAnchor.constraint(equalToConstant: 44).isActive = true return item }
这个方案的核心是用容器视图和导航栏的布局系统交互,内部的目标视图完全遵循你设置的尺寸规则,不会被系统逻辑覆盖。
解决方案二:提升约束优先级+手动控制间距
如果你不想新增容器视图,可以尝试提升尺寸约束的优先级,同时通过fixedSpace来手动控制按钮间距:
- 先修改你的
anchor方法,把约束优先级设为最高:
extension UIView { func anchor(to size: CGSize) { translatesAutoresizingMaskIntoConstraints = false let constraints = [ heightAnchor.constraint(equalToConstant: size.height).priority(.required), widthAnchor.constraint(equalToConstant: size.width).priority(.required) ] NSLayoutConstraint.activate(constraints) } }
- 手动插入固定间距的BarButtonItem,替代系统默认的宽间距:
var barButtonItems: [UIBarButtonItem] = [] for v in views { v.anchor(to: CGSize(width: 12, height: 12)) let item = UIBarButtonItem(customView: v) if #available(iOS 26.0, *) { item.hidesSharedBackground = true } barButtonItems.append(item) // 给除了最后一个按钮的所有按钮后插入固定间距 if v != views.last { let spaceItem = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) spaceItem.width = 8 // 这个值可以对照iOS 18的效果微调 barButtonItems.append(spaceItem) } } navigationItem.rightBarButtonItems = barButtonItems
额外注意点
- 你代码里的
iOS 26.0应该是笔误吧?目前iOS最新版本才到17.x,但不管具体版本号,只要是新版本出现的布局差异,上面的方案都适用 - 按钮的点击区域别太小,导航栏按钮默认的舒适点击区域是44x44,太小会导致用户点击体验变差
你可以先试试第一个方案,我自己处理类似问题时,套容器视图的方式几乎能解决所有新版本导航栏的布局兼容性问题。




