Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent multiple Tap on the same UIButton

Some times in my app I get this error because the UI freezes and the users tap more than once the buttons:

"pushing the same view controller instance more than once is not supported"

I have tried this:

How to prevent multiple event on same UIButton in iOS?

And it works like a charm but if my tabbar has more than 5 elements if I tab the button that shows an element greater than 5 the more button animates from left to right.

Is there other way to prevent the double tab in an easy way that does not use animations?.

This is the code I'm using:

- (IBAction)btnAction:(id)sender {
    UIButton *bCustom = (UIButton *)sender;
    bCustom.userInteractionEnabled = NO;
    [UIView animateWithDuration:1.0 delay:0.0 options:UIViewAnimationOptionAllowAnimatedContent animations:^{
        [self selectTabControllerIndex:bCustom.tag];
    } completion:^(BOOL finished){
        bCustom.userInteractionEnabled = YES;
    }];
}
like image 617
Stornu2 Avatar asked May 20 '16 08:05

Stornu2


1 Answers

it seems that under iOS 14.x it will happen automatically when You tap.

I have written small demo app with a nav controller, a controller of class "ViewController" with a button invoking an action "pushIt".

(see code) I have set Storyboard ID to a separated controller to "ColoredVCID" and added a global counter, just to see...

Long way SHORT: it seems working correctly.

//  compulsiveTouch
//
//  Created by ing.conti on 03/08/21.
 
   import UIKit
    
    fileprivate var cont = 0
    
    class ViewController: UIViewController {
    
        @IBAction func pushIt(_ sender: Any) {
            
            cont+=1
            print(cont)
    
            let storyboard = UIStoryboard(name: "Main", bundle: nil)
            let vc = storyboard.instantiateViewController(withIdentifier: "ColoredVCID")
            self.navigationController!.present(vc, animated: true)
            // OR:
            self.navigationController!.pushViewController(vc, animated: true)
        }
    
    }

In PAST days I usually did:

   @objc func pushItOLD(_sender: Any){

        // prevent compulsive touch:
        self.setButtonActive(btn: self.pushBtn!, active: false)
        // now re-eanble it... after 1 second:
        let when = DispatchTime.now() + 1
        DispatchQueue.main.asyncAfter(deadline: when, execute: { () -> Void in

            self.setButtonActive(btn: self.pushBtn!, active: true)
        })


    }
    
    func setButtonActive(btn: UIButton?,  active: Bool){
        guard let btn = btn else{
            return
        }
        btn.isEnabled = active
        btn.alpha = (active ? 1 : 0.5)
    }

that CAN BE very useful nowadays if your button for example invokes a network request... to prevent double calls.

(I added some cosmetics to use alpha.. to let user see it as "disabled" ..)

like image 105
ingconti Avatar answered Sep 18 '22 22:09

ingconti