自定义UIButton:大按钮帧小可视区域高度异常问题求助
需求描述
- 创建UIButton子类,具备44pt的大点击区域,但仅显示24pt大小的背景视图
- 按钮点击需添加背景动画,因此使用
backgroundImage实现背景
现有代码
自定义Button子类
public final class BigSmallButton: UIButton { ... public override var buttonType: UIButton.ButtonType { return .custom } override init(frame: CGRect) { super.init(frame: frame) NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 44).isActive = true let imageSize = CGSize(width: 24, height: 24) let backgroundImage = UIImage.image(with: Constants.buttonBackgroundColor, size: imageSize) setBackgroundImage(backgroundImage, for: .normal) layer.cornerRadius = Constants.buttonIconSize.height / 2.0 layer.masksToBounds = true layer.frame = CGRect(x: 0, y: 0, width: bounds.width, height: imageSize.height) }
添加到导航栏
let bigSmallButton = BigSmallButton(frame: .zero) navigationItem.rightBarButtonItem = UIBarButtonItem(customView: bigSmallButton)
问题
代码可运行,但按钮实际高度为24pt而非预期的44pt,请问是否可实现此类按钮?若可行,问题出在哪里?
解决方案
完全可以实现这种「大点击区域+小显示视图」的按钮,问题出在你直接修改了layer.frame,这会覆盖AutoLayout设置的高度约束,导致按钮高度被强制改成24pt。
修正步骤:
- 删除
layer.frame的赋值代码:AutoLayout已经设置了按钮高度为44pt,手动修改layer的frame会破坏布局系统的工作逻辑。 - 调整背景图片的显示模式:默认
backgroundImage会拉伸填充整个按钮,需设置让它居中显示且不拉伸,在设置背景图片后添加:contentMode = .center - 可选:添加宽度约束:为保证点击区域是正方形,可补充44pt的宽度约束,让按钮的点击范围更规整。
修正后的关键代码片段:
override init(frame: CGRect) { super.init(frame: frame) // 保留高度约束 NSLayoutConstraint(item: self, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 44).isActive = true // 添加宽度约束,保证正方形点击区域 NSLayoutConstraint(item: self, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 44).isActive = true let imageSize = CGSize(width: 24, height: 24) let backgroundImage = UIImage.image(with: Constants.buttonBackgroundColor, size: imageSize) setBackgroundImage(backgroundImage, for: .normal) // 设置背景图居中显示,不拉伸 contentMode = .center layer.cornerRadius = imageSize.height / 2.0 layer.masksToBounds = true // 移除layer.frame的赋值代码 }
补充说明:
- 导航栏的
UIBarButtonItem使用customView时,会优先遵循customView的AutoLayout约束,只要按钮约束正确,就能获得44pt的点击区域。 - 若要实现点击背景动画,可通过设置不同状态(
.highlighted、.selected)的backgroundImage,或在touchDown/touchUpInside事件中添加动画代码。
内容的提问来源于stack exchange,提问作者Денис Солодовник
相关产品推荐
相关产品推荐

