如何创建固定尺寸带自定义图标的UIBarButtonItem并适配图标尺寸?
我来帮你搞定这两个导航栏按钮的问题,分两部分一步步说:
一、修复“drop”按钮的交互区域,让它和Compose按钮尺寸一致
你的drop按钮交互区域被扩展,大概率是因为自定义View的intrinsicContentSize没有正确匹配图标尺寸,或者包装成UIBarButtonItem时强制设置了不合适的宽度。试试下面的方法:
步骤1:用UIButton作为自定义View(推荐)
如果你的drop按钮是用UIView包装的,换成UIButton更方便控制点击区域和图标展示:
// 1. 创建按钮并设置图标 let dropButton = UIButton(type: .custom) let dropIcon = UIImage(named: "drop-icon")?.withRenderingMode(.alwaysTemplate) // 适配导航栏 tintColor dropButton.setImage(dropIcon, for: .normal) // 2. 调整按钮内边距,让图标完全贴合按钮边界(关键!) // 根据你的图标尺寸调整,比如图标是24x24,内边距设为0或者很小的值 dropButton.contentEdgeInsets = UIEdgeInsets(top: 4, left: 4, bottom: 4, right: 4) // 3. 添加点击事件 dropButton.addTarget(self, action: #selector(dropButtonTapped), for: .touchUpInside) // 4. 包装成UIBarButtonItem let dropBarButton = UIBarButtonItem(customView: dropButton)
步骤2:让系统自动适配尺寸
不要给dropBarButton手动设置width属性,系统会根据UIButton的intrinsicContentSize(由图标尺寸+内边距计算)来确定按钮的实际大小,这样就会和默认的Compose按钮尺寸保持一致。
如果还是有问题,可以检查下Compose按钮的尺寸,然后给dropButton的intrinsicContentSize做手动适配:
extension UIButton { override open var intrinsicContentSize: CGSize { let iconSize = CGSize(width: 24, height: 24) // 和Compose图标尺寸一致 return CGSize(width: iconSize.width + contentEdgeInsets.left + contentEdgeInsets.right, height: iconSize.height + contentEdgeInsets.top + contentEdgeInsets.bottom) } }
二、创建固定尺寸的自定义图标UIBarButtonItem
如果需要按钮严格保持某个固定尺寸(比如24x24、30x30),可以用以下两种方法:
方法1:使用自定义UIView(精确控制尺寸)
func createFixedSizeBarButtonItem(iconName: String, target: Any?, action: Selector?) -> UIBarButtonItem { // 1. 创建固定尺寸的容器View let customView = UIView(frame: CGRect(x: 0, y: 0, width: 24, height: 24)) // 2. 添加图标按钮 let button = UIButton(type: .custom) button.frame = customView.bounds let icon = UIImage(named: iconName)?.withRenderingMode(.alwaysTemplate) button.setImage(icon, for: .normal) button.contentMode = .scaleAspectFit // 让图标适配按钮尺寸 // 3. 添加点击事件 if let target = target, let action = action { button.addTarget(target, action: action, for: .touchUpInside) } customView.addSubview(button) // 4. 包装成BarButtonItem return UIBarButtonItem(customView: customView) } // 使用示例 let fixedSizeButton = createFixedSizeBarButtonItem(iconName: "your-icon", target: self, action: #selector(buttonTapped)) navigationItem.rightBarButtonItems = [fixedSizeButton, composeButton]
方法2:使用UIBarButtonItem.Configuration(iOS 14+推荐)
iOS 14及以上可以用Configuration来更灵活地设置按钮样式,包括固定尺寸相关的参数:
func createConfiguredBarButtonItem(iconName: String, target: Any?, action: Selector?) -> UIBarButtonItem { var config = UIBarButtonItem.Configuration.plain() config.image = UIImage(named: iconName)?.withRenderingMode(.alwaysTemplate) config.imagePadding = 4 // 调整图标和按钮边界的间距 config.preferredSize = .medium // 系统预设尺寸,也可以通过调整imageInsets来控制实际大小 // 如果需要更精确的尺寸,也可以结合customView使用Configuration let button = UIButton(type: .custom) button.configuration = config button.frame = CGRect(x: 0, y: 0, width: 28, height: 28) // 固定尺寸 if let target = target, let action = action { button.addTarget(target, action: action, for: .touchUpInside) } return UIBarButtonItem(customView: button) }
注意事项
- 确保你的图标资源是正确的尺寸(比如@2x、@3x版本齐全),避免拉伸模糊;
- 如果导航栏的
tintColor没有正确应用到图标,记得给UIImage设置withRenderingMode(.alwaysTemplate); - 测试时可以给自定义View加个背景色(比如
customView.backgroundColor = .red),直观查看按钮的实际大小和点击区域。
内容的提问来源于stack exchange,提问作者quangkid
相关产品推荐
相关产品推荐

