iOS-TD-UIButton同时点击&&重复点击规避

参考文档

iOS-button防止被重复点击的相关方法(详细版)
iOS小技巧:用runtime 解决UIButton 重复点击问题

一、避免屏幕内多个button被同时点击

  • AppDelegate中添加[[UIButton appearance] setExclusiveTouch:YES];
  • 或者每新建button都设置button.exclusiveTouch = YES;

setExclusiveTouch简介

  • setExclusiveTouch此方法iOS8以上
  • setExclusiveTouch是UIView的一个属性,默认为NO(不互斥),设置UIView接收手势的互斥性为YES,防止多个响应区域被“同时”点击,“同时”响应的问题。
  • 可以通过 [[UIView appearance] setExclusiveTouch:YES]; UIImageView ,UILabel等,都可以添加手势,响应方式和UIButton相同。全局设置响应区域的点击手势的互斥,是有效的。

二、performSelector:withObject:afterDelay:在每次点击时先取消之前的操作

- (void)buttonClicked:(id)sender
{
   //这里是关键,点击按钮后先取消之前的操作,再进行需要进行的操作
   [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(buttonClicked:) object:sender];
   [self performSelector:@selector(buttonClicked: )withObject:sender afterDelay:0.2f];
}

三、performSelector:withObject:afterDelay:点击后将按钮置为不可点击状态,几秒后恢复

-(void)buttonClicked:(id)sender{
   self.button.enabled = NO;
   [self performSelector:@selector(changeButtonStatus) withObject:nil afterDelay:1.0f];//防止用户重复点击
}

-(void)changeButtonStatus{
    self.button.enabled = YES;
}

四、使用Runtime对UIButton进行设置

#import

#define defaultInterval.5//默认时间间隔

@interfaceUIControl (UIControl_buttonCon)

@property(nonatomic,assign)NSTimeIntervaltimeInterval;//用这个给重复点击加间隔

@property(nonatomic,assign)BOOLisIgnoreEvent;//YES不允许点击NO允许点击

@end
#import"UIControl+UIControl_buttonCon.h"

@implementationUIControl (UIControl_buttonCon)

- (NSTimeInterval)timeInterval

{

return[objc_getAssociatedObject(self,_cmd)doubleValue];

}

- (void)setTimeInterval:(NSTimeInterval)timeInterval

{

objc_setAssociatedObject(self,@selector(timeInterval),@(timeInterval),OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

//runtime动态绑定属性

- (void)setIsIgnoreEvent:(BOOL)isIgnoreEvent{

objc_setAssociatedObject(self,@selector(isIgnoreEvent),@(isIgnoreEvent),OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (BOOL)isIgnoreEvent{

return[objc_getAssociatedObject(self,_cmd)boolValue];

}

- (void)resetState{

[selfsetIsIgnoreEvent:NO];

}

+ (void)load{

staticdispatch_once_tonceToken;

dispatch_once(&onceToken, ^{

SELselA =@selector(sendAction:to:forEvent:);

SELselB =@selector(mySendAction:to:forEvent:);

MethodmethodA =class_getInstanceMethod(self, selA);

MethodmethodB =class_getInstanceMethod(self, selB);

//将methodB的实现添加到系统方法中也就是说将methodA方法指针添加成方法methodB的返回值表示是否添加成功

BOOLisAdd =class_addMethod(self, selA,method_getImplementation(methodB),method_getTypeEncoding(methodB));

//添加成功了说明本类中不存在methodB所以此时必须将方法b的实现指针换成方法A的,否则b方法将没有实现。

if(isAdd) {

class_replaceMethod(self, selB,method_getImplementation(methodA),method_getTypeEncoding(methodA));

}else{

//添加失败了说明本类中有methodB的实现,此时只需要将methodA和methodB的IMP互换一下即可。

method_exchangeImplementations(methodA, methodB);

}

});

}

- (void)mySendAction:(SEL)action to:(id)target forEvent:(UIEvent*)event

{

if([NSStringFromClass(self.class)isEqualToString:@"UIButton"]) {

self.timeInterval=self.timeInterval==0?defaultInterval:self.timeInterval;

if(self.isIgnoreEvent){

return;

}elseif(self.timeInterval>0){

[selfperformSelector:@selector(resetState)withObject:nilafterDelay:self.timeInterval];

}

}

//此处methodA和methodB方法IMP互换了,实际上执行sendAction;所以不会死循环

self.isIgnoreEvent=YES;

[selfmySendAction:actionto:targetforEvent:event];

}

@end

你可能感兴趣的:(iOS-TD-UIButton同时点击&&重复点击规避)