UINavigationController右侧双按钮时标题偏移及间距过大问题
最优解决方案:用UIStackView包裹按钮作为单个BarButtonItem
系统自带的多BarButtonItem间距是固定的,且自定义View的BarButtonItem无法通过width属性或fixedSpace调整间距,最稳定的方式是把两个按钮放进UIStackView,再将StackView作为单个BarButtonItem的自定义视图,既能精准控制按钮间距,又能保证标题始终居中。
代码示例:
// 先给按钮添加尺寸约束(确保按钮大小符合预期) btnGoToScan.widthAnchor.constraint(equalToConstant: 24).isActive = true btnGoToScan.heightAnchor.constraint(equalToConstant: 24).isActive = true btnExportImage.widthAnchor.constraint(equalToConstant: 24).isActive = true btnExportImage.heightAnchor.constraint(equalToConstant: 24).isActive = true // 创建水平StackView,设置间距 let buttonStack = UIStackView(arrangedSubviews: [btnGoToScan, btnExportImage]) buttonStack.axis = .horizontal buttonStack.spacing = 8 // 这里设置你想要的按钮间距,比如4/8都可以 buttonStack.alignment = .center // 将StackView作为单个BarButtonItem的自定义视图 let rightBarItem = UIBarButtonItem(customView: buttonStack) navigationItem.rightBarButtonItem = rightBarItem
为什么之前的方法无效?
- 自定义View的
UIBarButtonItem的width属性不生效,系统会优先使用自定义视图的固有内容尺寸来计算宽度。 - iOS11之后导航栏采用自动布局体系,
fixedSpace对自定义View的BarButtonItem间距调整效果有限,系统会给每个自定义BarButtonItem默认添加额外内边距,导致间距无法缩小。 - 多个独立BarButtonItem会让系统计算右侧总宽度,当宽度超过阈值时,会挤压标题导致偏移;合并成单个item后,系统只会计算StackView的整体宽度,标题居中逻辑更稳定。
补充:如果一定要用多个BarButtonItem(不推荐)
如果坚持使用多BarButtonItem,需要给自定义按钮手动设置intrinsicContentSize,同时调整fixedSpace的数值,但这种方式兼容性较差,不同iOS版本可能有差异:
// 给按钮设置固有尺寸 class CustomBarButton: UIButton { override var intrinsicContentSize: CGSize { return CGSize(width: 24, height: 24) } } // 然后创建按钮和间距 let item1 = UIBarButtonItem(customView: btnGoToScan) let item2 = UIBarButtonItem(customView: btnExportImage) let negativeSpace = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) negativeSpace.width = -12 // 调整这个数值直到间距符合预期 navigationItem.setRightBarButtonItems([item1, negativeSpace, item2], animated: false)
内容的提问来源于stack exchange,提问作者Afinainflowers
相关产品推荐
相关产品推荐

