自定义类型UIButton的IBAction触发延迟问题求助
这个坑我之前踩过!你遇到的延迟问题,核心原因是UITextField的触摸事件优先级比内部的Custom按钮高——当你点击按钮时,UITextField会先处理自身的触摸逻辑(比如触发编辑状态、准备弹出键盘),导致按钮的点击事件被“卡”了几秒才传递到IBAction。而System类型的按钮是苹果做了特殊优化的,能跳过TextField的事件拦截,所以响应正常,但代价就是图片会被系统用tintColor(默认蓝色)渲染。
给你几个靠谱的解决办法:
方法一:让Custom按钮优先接收触摸事件(最推荐)
自定义一个UITextField子类,重写hitTest方法,让触摸点落在按钮范围内时,直接把事件交给按钮处理,跳过TextField的事件逻辑。
Swift代码示例:
class PriorityButtonTextField: UITextField { // 假设你的按钮在TextField里的tag设为100,记得在IB里给按钮设置对应tag override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { guard let button = viewWithTag(100) as? UIButton else { return super.hitTest(point, with: event) } // 把TextField坐标系的触摸点转换为按钮坐标系的点 let buttonLocalPoint = convert(point, to: button) // 如果触摸点在按钮范围内,返回按钮,让它优先处理事件 if button.bounds.contains(buttonLocalPoint) { return button } return super.hitTest(point, with: event) } }
然后在IB里把你的UITextField的Class改成PriorityButtonTextField,给按钮设置tag=100,这样点击按钮时就会瞬间响应,不会有延迟了。
Objective-C代码示例:
@interface PriorityButtonTextField : UITextField @end @implementation PriorityButtonTextField - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIButton *targetButton = (UIButton *)[self viewWithTag:100]; if (targetButton) { CGPoint buttonPoint = [self convertPoint:point toView:targetButton]; if (CGRectContainsPoint(targetButton.bounds, buttonPoint)) { return targetButton; } } return [super hitTest:point withEvent:event]; } @end
方法二:给按钮设置独占触摸(辅助优化)
在代码里给按钮加上exclusiveTouch属性,让它独占触摸事件,避免和TextField的事件冲突:
yourButton.exclusiveTouch = true
这个方法可以配合方法一使用,进一步确保事件不会被拦截,但单独用可能效果不如方法一彻底。
这样处理后,你既可以保留Custom类型按钮的原始图片颜色,又能让IBAction瞬间触发,完美解决你的问题~
内容的提问来源于stack exchange,提问作者Mohan Ramanathan
相关产品推荐
相关产品推荐

