如何移除UIButton长按状态下的阴影?现有方案未生效求助
问题分析与解决方案
你的方案没生效主要有几个关键问题,而且其实完全不需要用长按手势来实现这个需求——UIButton本身就有原生的高亮状态可以利用,更简单可靠。
先说说你的手势方案为什么失效:
- 长按手势的参数设置错误:你给
numberOfTapsRequired设了1,这意味着这个手势需要先点击一次再长按才会触发,完全不符合你“触摸按钮时就移除阴影”的需求,应该把这个值改成0(或者直接删掉这个设置,默认就是0)。 - 手势与按钮原生事件冲突:UIButton是
UIControl的子类,它内部有自己的触摸事件处理逻辑,优先级比手势识别器高,所以你的手势可能根本没被触发。即使调整delaysTouchesBegan这类参数,也很难保证和按钮原生行为不冲突。 - 手势状态判断错误:你监听的
.recognized状态是长按手势完成识别(达到minimumPressDuration时长)后的状态,但你需要的是触摸开始时就隐藏阴影,应该监听.began状态;而触摸结束时应该同时处理.ended和.cancelled状态(比如用户触摸后滑动到按钮外,会触发.cancelled)。
更靠谱的两种实现方式:
方式一:重写UIButton的isHighlighted属性(推荐)
按钮的isHighlighted属性会在触摸时自动变为true,松开时变回false,直接监听这个属性的变化是最贴合需求的方案:
class ShadowToggleButton: UIButton { // 初始化时设置基础阴影 override init(frame: CGRect) { super.init(frame: frame) setupShadow() } required init?(coder: NSCoder) { super.init(coder: coder) setupShadow() } private func setupShadow() { layer.shadowColor = UIColor.black.cgColor layer.shadowOffset = CGSize(width: 0, height: 2) layer.shadowRadius = 4 layer.shadowOpacity = 0.15 layer.masksToBounds = false // 必须关闭这个,否则阴影会被裁剪 } // 重写高亮属性,自动处理阴影显示/隐藏 override var isHighlighted: Bool { didSet { UIView.animate(withDuration: 0.1) { self.layer.shadowOpacity = self.isHighlighted ? 0 : 0.15 } } } }
方式二:监听按钮的UIControl事件
如果你不想自定义按钮,也可以直接给按钮添加触摸事件监听:
// 在viewDidLoad或按钮初始化时添加事件 yourButton.addTarget(self, action: #selector(onButtonTouchDown), for: .touchDown) yourButton.addTarget(self, action: #selector(onButtonTouchEnd), for: [.touchUpInside, .touchUpOutside, .touchCancel]) // 响应方法 @objc private func onButtonTouchDown(_ sender: UIButton) { UIView.animate(withDuration: 0.1) { sender.layer.shadowOpacity = 0 } } @objc private func onButtonTouchEnd(_ sender: UIButton) { UIView.animate(withDuration: 0.1) { sender.layer.shadowOpacity = 0.15 } }
额外提醒:
别忘了检查按钮的layer.masksToBounds属性,如果这个值是true,阴影会被按钮的边界裁剪掉,永远看不到,所以必须设置为false。
内容的提问来源于stack exchange,提问作者sushibrain
相关产品推荐
相关产品推荐

