crazydev
crazydev

Reputation: 103

How to prevent multiple event on same UIButton in iOS?

I want to prevent continuous multiple clicks on the same UIButton.

I tried with enabled and exclusiveTouch properties but it didn't work. Such as:

-(IBAction) buttonClick:(id)sender{
    button.enabled = false;
    [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowAnimatedContent animations:^{
        // code to execute
     }
     completion:^(BOOL finished){
         // code to execute  
    }];
    button.enabled = true;
}

Upvotes: 9

Views: 13501

Answers (4)

IuryPainelli
IuryPainelli

Reputation: 335

Instead of using UIView animation I decided to use the Timer class to enable the button after a time interval. Here is the answer using Swift 4:

@IBAction func didTouchButton(_ sender: UIButton) {
    sender.isUserInteractionEnabled = false

    //Execute your code here

    Timer.scheduledTimer(withTimeInterval: 2, repeats: false, block: { [weak sender] timer in
        sender?.isUserInteractionEnabled = true
    })
}

Upvotes: 3

Murray Sagal
Murray Sagal

Reputation: 8674

In my case setting isEnabled was not fast enough to prevent multiple taps. I had to use a property and a guard to prevent multiple taps. And the action method is calling a delegate which normally dismisses the view controller but with multiple button taps it was not dismissing. dismiss(...) must cancel itself if code is still executing on the view controller, not sure. Regardless, I had to add a manual dismiss in the guard.

Here's my solution...

private var didAlreadyTapDone = false
private var didNotAlreadyTapDone: Bool {return !didAlreadyTapDone}

func done() {
    guard didNotAlreadyTapDone else {
        self.dismiss(animated: true, completion: nil)
        return
    }
    didAlreadyTapDone = true
    self.delegate.didChooseName(name)
}

Upvotes: 0

ylgwhyh
ylgwhyh

Reputation: 1598

This is my solution:

NSInteger _currentClickNum; //Save the current value of the tag button is clicked

//Button click event
- (void)tabBt1nClicked:(UIButton *)sender
{
    NSInteger index = sender.tag;
    if (index == _currentClickNum) {
        NSLog(@"Click on the selected current topic, not execution method, avoiding duplicate clicks");
    }else {
        [[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(tabBtnClicked:) object:sender];
        sender.enabled = NO;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            sender.enabled = YES;
        });
        _currentClickNum = index;
        NSLog(@"Column is the current click:%ld",_currentClickNum);
    }
}

Upvotes: 0

Hemang
Hemang

Reputation: 27072

What you're doing is, you simply setting enabled on/off outside of the block. This is wrong, its executing once this method will call, thus its not disabling the button until completion block would call. Instead you should reenable it once your animation would get complete.

-(IBAction) buttonClick:(id)sender{
    button.enabled = false;
    [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowAnimatedContent animations:^{
        // code to execute
     }
     completion:^(BOOL finished){
         // code to execute  
        button.enabled = true; //This is correct.
    }];
    //button.enabled = true; //This is wrong.
}

Oh and yes, instead of true and false, YES and NO would looks nice. :)

Upvotes: 15

Related Questions