IOS tips-use runtime to solve UIButton repeated clicks
IOS tips-use runtime to solve the UIButton repeated click problem. What is this problem?
Our button is a response once, even if you click frequently, there will be no problems, but in some scenarios, there will also be problems.
How to solve this problem
We usually set this button when the button is clicked. Wait for the delay of 0. xS, and then set it back. Or you can click it at the end of the operation.
- (IBAction)clickBtn1:(UIbutton *)sender{ sender.enabled = NO; doSomething sender.enabled = YES;}
Enabled may not be enough for different buttons in different States. An additional variable is required to record the status.
- (IBAction)clickBtn1:(UIbutton *)sender{ if (doingSomeThing) return; doingSomeThing = YES; doSomething doingSomeThing = NO;}
In my example, click is directly prohibited during the response period. If you want to disable repeated clicks within 1 second, you must useperformSelector:withObject:afterDelay:
What is the beautiful solution?
With repeated code segments, We can abstract them out with a commonality.
We can add an attribute to the button.Repeated click Interval
, You can set this attribute to control the interval for accepting click events again.
@ Interface UIControl (XY) @ property (nonatomic, assign) NSTimeInterval interval; // The interval @ endstatic const char * UIControl_acceptEventInterval = UIControl_acceptEventInterval;-(NSTimeInterval) uxy_acceptEventInterval {return [random (self, UIControl_acceptEventInterval) doubleValue];}-(void) random :( NSTimeInterval) random {random (self, UIControl_acceptEventInterval, @ (random), random );}
When the app is started, we hook the event of all the buttons
@implementation UIControl (XY)+ (void)load{ Method a = class_getInstanceMethod(self, @selector(sendAction:to:forEvent:)); Method b = class_getInstanceMethod(self, @selector(__uxy_sendAction:to:forEvent:)); method_exchangeImplementations(a, b);}@end
In our click events, filter click events
- (void)__uxy_sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event{ if (self.uxy_ignoreEvent) return; if (self.uxy_acceptEventInterval > 0) { self.uxy_ignoreEvent = YES; [self performSelector:@selector(setUxy_ignoreEvent:) withObject:@(NO) afterDelay:self.uxy_acceptEventInterval]; } [self __uxy_sendAction:action to:target forEvent:event];}
Actually, this is what it looks like.
UIButton *tempBtn = [UIButton buttonWithType:UIButtonTypeCustom]; [tempBtn addTarget:self action:@selector(clickWithInterval:) forControlEvents:UIControlEventTouchUpInside]; tempBtn.uxy_acceptEventInterval = 0.5;
This article has ended. Although it is not recommended to use a wide range of runtime, it can solve many small problems in a small scope.