用Runtime解决UIButton重复点击问题
通常我们在项目中会遇到这样的问题,点击一个button触发一个事件,但总是会遇到连点的问题,如果是动画,连点会让你的动画出现意想不到的情况。我在之前的项目中也遇到过类似的情况,上网搜过很多解决方法,但都没有得到想要解决方案。前几天在cocoachina一篇文章中得到启发,自己写了一Demo共享给大家。废话不多说先上图,没图说个jiba .
两个button的点击事件完全相同,都是让红色的view的中心点从(25,89)到(200,500)但很明显没做控制的button在多次点击的情况下动画不是我们想要的效果。
再上代码
@interface UIControl (YN)
@property (nonatomic, assign) NSTimeInterval hyn_acceptEventInterval;//添加点击事件的间隔事件
@property (nonatomic, assign) BOOL hyn_ignoreEvent;//
@end
#import@implementation UIControl (YN)
static const char *UIControl_acceptEventInterval = "UIControl_acceptEventInterval";
static const char *UIcontrol_ignoreEvent = "UIcontrol_ignoreEvent";
- (NSTimeInterval)hyn_acceptEventInterval {
return [objc_getAssociatedObject(self, UIControl_acceptEventInterval) doubleValue];
}
- (void)setHyn_acceptEventInterval:(NSTimeInterval)hyn_acceptEventInterval {
objc_setAssociatedObject(self, UIControl_acceptEventInterval, @(hyn_acceptEventInterval), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (BOOL)hyn_ignoreEvent {
return [objc_getAssociatedObject(self, UIcontrol_ignoreEvent) boolValue];
}
- (void)setHyn_ignoreEvent:(BOOL)hyn_ignoreEvent {
objc_setAssociatedObject(self, UIcontrol_ignoreEvent, @(hyn_ignoreEvent), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
+ (void)load {
Method a = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:));
Method b = class_getInstanceMethod(self, @selector(__hyn_sendAction:to:forEvent:));
method_exchangeImplementations(a, b);
}
- (void)__hyn_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event {
if (self.hyn_ignoreEvent) return;
if (self.hyn_acceptEventInterval > 0) {
self.hyn_ignoreEvent = YES;
[self performSelector:@selector(setHyn_ignoreEvent:) withObject:@(NO) afterDelay:self.hyn_acceptEventInterval];
}
[self __hyn_sendAction:action to:target forEvent:event];
}
@end
使用:
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIButton *button;//用Runtime做控制的button
@property (weak, nonatomic) IBOutlet UIView *colorView;//红色的view
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//设置一个延迟时间,为了方便观察我这里把动画设置成三秒
self.button.hyn_acceptEventInterval = 3;
}
//Runtime控制的button点击事件
- (IBAction)runtimeAction:(UIButton *)sender {
[UIView animateWithDuration:3 animations:^{
self.colorView.center = CGPointMake(200, 500);
} completion:^(BOOL finished) {
self.colorView.center = CGPointMake(25, 89);
}];
}
//普通的buttonAction
- (IBAction)buttonAction:(UIButton *)sender {
[UIView animateWithDuration:3 animations:^{
self.colorView.center = CGPointMake(200, 500);
} completion:^(BOOL finished) {
self.colorView.center = CGPointMake(25, 89);
}];
}
@end
为了方便看代码截个图,这年头没图就是没把发说事
你还在一个一个单独控制多次点击吗?采用Runtime的方法,让你简单到1行代码解决重复点击问题
self.button.hyn_acceptEventInterval = 0.xx;
就是那么简单。
文章灵感来自Cocoachina