iOS 10与iOS 11中UIBarButtonItems间距差异过大问题求助
嘿,我刚好碰到过类似的情况!iOS 11之后苹果对导航栏的布局逻辑做了不少调整,尤其是UIBarButtonItem的默认间距计算,在iOS 10及更早的系统上,小屏幕设备(比如iPhone 5s)的默认间距确实会偏大。结合你用标签管理点击逻辑的需求,给你几个靠谱的解决方案:
方案1:自定义UIButton包装成UIBarButtonItem(最推荐)
这种方法完全摆脱系统默认的布局限制,精准控制每个图标的大小和间距,而且你的标签点击逻辑完全不受影响。
步骤如下:
- 写一个工具方法创建自定义按钮:
@objc private func socialButtonTapped(_ sender: UIButton) { // 你的点击逻辑,根据sender.tag判断处理 switch sender.tag { case 1: // 处理第一个社交平台 break case 2: // 处理第二个社交平台 break default: break } } private func createSocialBarItem(tag: Int, imageName: String) -> UIBarButtonItem { let button = UIButton(type: .custom) button.tag = tag button.setImage(UIImage(named: imageName), for: .normal) button.addTarget(self, action: #selector(socialButtonTapped(_:)), for: .touchUpInside) // 匹配你的图标尺寸(24x24) button.frame = CGRect(x: 0, y: 0, width: 24, height: 24) // 如果用AutoLayout的话,替换上面的frame: // button.translatesAutoresizingMaskIntoConstraints = false // NSLayoutConstraint.activate([ // button.widthAnchor.constraint(equalToConstant: 24), // button.heightAnchor.constraint(equalToConstant: 24) // ]) return UIBarButtonItem(customView: button) }
- 创建按钮并添加到导航栏,用
fixedSpace控制间距:
let twitterItem = createSocialBarItem(tag: 1, imageName: "twitter") let facebookItem = createSocialBarItem(tag: 2, imageName: "facebook") // 自定义间距,这里设为8,你可以根据需求调整 let spaceItem = UIBarButtonItem(barButtonSystemItem: .fixedSpace, target: nil, action: nil) spaceItem.width = 8 navigationItem.rightBarButtonItems = [facebookItem, spaceItem, twitterItem]
这样不管是iOS 10还是iOS 11+,间距都是你设置的固定值,完全不会有系统差异的问题。
方案2:针对iOS 10调整imageInsets
如果你不想改太多代码,可以针对旧系统单独调整UIBarButtonItem的内边距,缩小默认间距:
let twitterItem = UIBarButtonItem(image: UIImage(named: "twitter"), style: .plain, target: self, action: #selector(socialButtonTapped(_:))) twitterItem.tag = 1 if #available(iOS 11.0, *) { // iOS11+保持默认即可 } else { // 调整内边距缩小间距,数值可以根据实际效果微调 twitterItem.imageInsets = UIEdgeInsets(top: 0, left: -8, bottom: 0, right: 8) } // 同理处理其他按钮... navigationItem.rightBarButtonItems = [facebookItem, twitterItem]
不过这种方法需要反复调试insets的数值,不如自定义视图精准,适合快速临时调整的场景。
方案3:用容器View整合所有按钮
如果你的社交图标比较多,可以把所有按钮放到一个UIView里,再把这个View包装成UIBarButtonItem,这样整体布局更灵活:
let socialContainer = UIView() socialContainer.translatesAutoresizingMaskIntoConstraints = false // 创建第一个按钮 let twitterBtn = UIButton(type: .custom) twitterBtn.tag = 1 twitterBtn.setImage(UIImage(named: "twitter"), for: .normal) twitterBtn.addTarget(self, action: #selector(socialButtonTapped(_:)), for: .touchUpInside) twitterBtn.translatesAutoresizingMaskIntoConstraints = false socialContainer.addSubview(twitterBtn) // 创建第二个按钮 let facebookBtn = UIButton(type: .custom) facebookBtn.tag = 2 facebookBtn.setImage(UIImage(named: "facebook"), for: .normal) facebookBtn.addTarget(self, action: #selector(socialButtonTapped(_:)), for: .touchUpInside) facebookBtn.translatesAutoresizingMaskIntoConstraints = false socialContainer.addSubview(facebookBtn) // 设置AutoLayout约束 NSLayoutConstraint.activate([ twitterBtn.centerYAnchor.constraint(equalTo: socialContainer.centerYAnchor), twitterBtn.rightAnchor.constraint(equalTo: facebookBtn.leftAnchor, constant: -8), // 按钮间距8 facebookBtn.centerYAnchor.constraint(equalTo: socialContainer.centerYAnchor), facebookBtn.rightAnchor.constraint(equalTo: socialContainer.rightAnchor), socialContainer.heightAnchor.constraint(equalToConstant: 24), twitterBtn.widthAnchor.constraint(equalToConstant: 24), twitterBtn.heightAnchor.constraint(equalToConstant: 24), facebookBtn.widthAnchor.constraint(equalToConstant: 24), facebookBtn.heightAnchor.constraint(equalToConstant: 24) ]) // 包装成UIBarButtonItem let socialBarItem = UIBarButtonItem(customView: socialContainer) navigationItem.rightBarButtonItems = [socialBarItem]
这种方式把所有图标作为一个整体的导航栏项,布局完全由你掌控,兼容性拉满。
不管用哪种方案,你的标签点击逻辑都可以正常工作,因为按钮的tag属性依然可以正常设置和判断~
内容的提问来源于stack exchange,提问作者jped
相关产品推荐
相关产品推荐

