UIButton的touchUpInside事件在触摸移出边界后仍触发要如何处理?
UIKit默认给UIButton内置了超出可视边界的触摸响应缓冲区域,即使用户手指移出按钮边界少量距离,系统仍然会判定触摸事件归属该按钮,因此touchUpInside事件会被触发。要实现「手指移出按钮边界就不触发touchUpInside」的严格判定逻辑,可采用以下方案:
方案1:自定义UIButton子类(最常用方案)
重写UIButton的pointInside:withEvent:方法,该方法是系统判定触摸点是否属于当前视图的核心方法,修改判定规则为严格匹配按钮自身bounds范围即可:
Objective-C代码
// CustomButton.h #import <UIKit/UIKit.h> @interface CustomButton : UIButton @end // CustomButton.m #import "CustomButton.h" @implementation CustomButton - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { // 严格判定触摸点是否在按钮可视范围内 return CGRectContainsPoint(self.bounds, point); } @end
Swift代码
import UIKit class CustomButton: UIButton { override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { return bounds.contains(point) } }
使用时将需要严格判定边界的按钮类设置为CustomButton即可。
方案2:适配圆角/异形按钮的精确判定
如果按钮是圆角、或者自定义异形形状,可以修改判定逻辑为判断触摸点是否在按钮的形状路径内,避免矩形边界判定的误触发:
class CustomShapeButton: UIButton { // 可自定义按钮的响应路径 private var hitPath: UIBezierPath { // 示例为按圆角判定,异形按钮可替换为自定义路径 return UIBezierPath(roundedRect: bounds, cornerRadius: layer.cornerRadius) } override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { return hitPath.contains(point) } }
注意事项
- 该修改会同时作用于按钮所有触摸事件的判定,包括touchDown、touchDrag等事件都会遵循相同的边界规则
- 如果需要保留少量的边界容错,可调整判定范围,例如允许超出边界2pt的容错范围,Swift写法为
return bounds.insetBy(dx: -2, dy: -2).contains(point),Objective-C写法为return CGRectContainsPoint(CGRectInset(self.bounds, -2, -2), point)
内容的提问来源于stack exchange,提问作者ximmyxiao
相关产品推荐
相关产品推荐

