我相信很多开发遇到过测试或者其它人员说这个按钮怎么可以多点击,具体可参见下图
![](https://img.haomeiwen.com/i11066072/1770d6fbd3f6cbd5.gif)
哎,怎么办呢?我去查过资料,说是在AppDelegate里面加个'[[UIButton appearance] setExclusiveTouch:YES];'但是似乎也没啥用,直到某天,鄙人在学runTime的时候,无意间看到一个说防多次点击的案例……
第一,你需要新建一个UIButton的类别作为扩展并导入运行时的头文件
在实现的地方输入以下代码
// 最小时间差
static NSTimeInterval insensitiveMinTimeInterval = 1.f;
// 原生sendAction:to:forEvent:实现
static void (*originalImplementation)(id, SEL, SEL, id, UIEvent *) = NULL;
static void replacedImplementation(id object, SEL selector, SEL action, id target, UIEvent *event);
第二,再去执行这些代码,并且把“+ (void)enableInsensitiveTouch;”放到.h文件中
+ (void)enableInsensitiveTouch
{
Method methodNow = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
IMP implementationNow = method_getImplementation(methodNow);
if (implementationNow == (IMP)replacedImplementation) {
return;
}
originalImplementation = (void (*)(id, SEL, SEL, id, UIEvent *))implementationNow;
const char *type = method_getTypeEncoding(methodNow);
class_replaceMethod(self, @selector(sendAction:to:forEvent:), (IMP)replacedImplementation, type);
}
+ (void)disableInsensitiveTouch
{
IMP implementationNow = class_getMethodImplementation(self, @selector(sendAction:to:forEvent:));
if (originalImplementation && implementationNow == (IMP)replacedImplementation)
{
class_replaceMethod(self, @selector(sendAction:to:forEvent:), (IMP)originalImplementation, NULL);
}
}
+ (void)setInsensitiveMinTimeInterval:(NSTimeInterval)interval
{
insensitiveMinTimeInterval = interval;
}
- (NSTimeInterval)lastTouchTimestamp
{
return [objc_getAssociatedObject(self, @selector(lastTouchTimestamp)) doubleValue];
}
- (void)setLastTouchTimestamp:(NSTimeInterval)timestamp
{
objc_setAssociatedObject(self, @selector(lastTouchTimestamp), @(timestamp), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
static void replacedImplementation(id object, SEL selector, SEL action, id target, UIEvent *event)
{
//如果不过滤掉 “ CUShutterButton”和 "CAMShutterButton",你就会发现app里弹出相机后,要长按才能拍照
if ( [object isKindOfClass:UIButton.self]
&& event.type == UIEventTypeTouches
&& ![NSStringFromClass([object class]) isEqualToString:@"CUShutterButton"]
&& ![NSStringFromClass([object class]) isEqualToString:@"CAMShutterButton"]
)
{
UIButton *button = (UIButton *)object;
if (ABS(event.timestamp - button.lastTouchTimestamp) < insensitiveMinTimeInterval) {
return;
}
button.lastTouchTimestamp = event.timestamp;
}
if (originalImplementation) {
originalImplementation(object, selector, action, target, event);
}
}
最后,还是在AppDelegate里面调用一下我们的UIButton的扩展
[UIButton enableInsensitiveTouch];
至此,大功告成了~~~,想要代码的同学,可以联系我~~~
网友评论