优化UIButton:实现更清晰的按压视觉反馈效果
1. 利用UIButton内置配置(iOS 15+)
iOS 15及以上版本的UIButton新增了configuration属性,可直接配置与系统按钮一致的按压反馈:
let customButton = UIButton(type: .system) // 初始化基础纯样式配置 var config = UIButton.Configuration.plain() config.title = "自定义按钮" // 设置常态与按压态背景 config.background.backgroundColor = .systemGray6 config.background.cornerRadius = 8 config.background.highlightedColor = .systemGray4 // 应用配置 customButton.configuration = config
这种方式无需额外逻辑,就能让按钮拥有和照片选择器按钮一致的按压视觉反馈。
2. 自定义高亮状态样式(兼容iOS 15以下)
针对低版本系统,可通过重写isHighlighted属性,手动切换按钮样式:
class HighlightableButton: UIButton { override var isHighlighted: Bool { didSet { // 切换背景色 backgroundColor = isHighlighted ? .systemGray4 : .systemGray6 // 可选:添加缩放动画强化反馈 UIView.animate(withDuration: 0.1) { self.transform = self.isHighlighted ? CGAffineTransform(scaleX: 0.95, y: 0.95) : .identity } } } override init(frame: CGRect) { super.init(frame: frame) setupBaseStyle() } required init?(coder: NSCoder) { super.init(coder: coder) setupBaseStyle() } private func setupBaseStyle() { backgroundColor = .systemGray6 layer.cornerRadius = 8 setTitle("自定义按钮", for: .normal) setTitleColor(.systemBlue, for: .normal) } }
这种方式完全自定义,可根据需求调整高亮时的颜色、缩放比例等细节。
3. 添加按压波纹效果(模拟系统触感)
如果想要类似系统的波纹扩散反馈,可通过触摸事件实现:
class RippleButton: UIButton { private var rippleLayer: CAShapeLayer? override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesBegan(touches, with: event) guard let touch = touches.first else { return } let touchPoint = touch.location(in: self) // 创建波纹图层 rippleLayer = CAShapeLayer() rippleLayer?.fillColor = UIColor.systemGray3.withAlphaComponent(0.5).cgColor rippleLayer?.path = UIBezierPath(ovalIn: CGRect(x: touchPoint.x - 5, y: touchPoint.y - 5, width: 10, height: 10)).cgPath layer.addSublayer(rippleLayer!) // 波纹扩散动画 let scaleAnim = CABasicAnimation(keyPath: "transform.scale") scaleAnim.fromValue = 1 scaleAnim.toValue = max(bounds.width, bounds.height) / 10 let alphaAnim = CABasicAnimation(keyPath: "opacity") alphaAnim.fromValue = 0.5 alphaAnim.toValue = 0 let groupAnim = CAAnimationGroup() groupAnim.animations = [scaleAnim, alphaAnim] groupAnim.duration = 0.6 groupAnim.fillMode = .forwards groupAnim.isRemovedOnCompletion = false rippleLayer?.add(groupAnim, forKey: "ripple") } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesEnded(touches, with: event) clearRipple() } override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { super.touchesCancelled(touches, with: event) clearRipple() } private func clearRipple() { rippleLayer?.removeAllAnimations() rippleLayer?.removeFromSuperlayer() rippleLayer = nil } override init(frame: CGRect) { super.init(frame: frame) setupBaseStyle() } required init?(coder: NSCoder) { super.init(coder: coder) setupBaseStyle() } private func setupBaseStyle() { backgroundColor = .systemGray6 layer.cornerRadius = 8 setTitle("波纹按钮", for: .normal) setTitleColor(.systemBlue, for: .normal) clipsToBounds = true } }
该实现能模拟系统按钮的波纹扩散触感,提升交互细腻度。
内容的提问来源于stack exchange,提问作者Cheok Yan Cheng
相关产品推荐
相关产品推荐

