防止多次点击同一个UIButton

时间:2016-05-20 08:34:33

标签: ios objective-c uibutton

有些时候,在我的应用中,我收到此错误,因为用户界面冻结,用户点按了多次按钮:

  

“多次推送同一个视图控制器实例不是   支持“

我试过这个:

How to prevent multiple event on same UIButton in iOS?

它就像一个魅力,但如果我的tabbar有超过5个元素,如果我选中显示大于5的元素的按钮,则从左到右动画的按钮越多。

是否有其他方法可以轻松防止双标签不使用动画?

这是我正在使用的代码:

- (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;
    }];
}

10 个答案:

答案 0 :(得分:6)

首先提示,如果您只有按钮调用该选择器,则可以将id更改为UIButton*并删除额外变量bCustom

现在,要解决您的问题,您需要确保在完成其他任何操作后,将userInteractionEnabled恢复为YES。使用动画块只是一种简单的方法,因为它内置了一个完成处理程序。

只需让selectTabControllerIndex方法为您完成工作,即可完成此操作。

这样的事情:

- (IBAction)btnAction:(UIButton*)sender {
    sender.userInteractionEnabled = NO;
    [self selectTabControllerForButton:sender];
}

- (void)selectTabControllerForButton:(UIButton*)sender {
    // Whatever selectTabControllerIndex does now goes here, use sender.tag as you used index
    sender.userInteractionEnabled = YES;
}

如果您之后可能需要执行其他代码,则可以在selectTabControllerIndex方法中添加完成处理程序,然后调用完成处理程序。在里面,你包括sender.userInteractionEnabled = YES;行。但如果它始终是相同的代码,第一种方式更容易,更快。

答案 1 :(得分:2)

对我有用的@Santo答案的Swift 4版本:

按钮代码:

@IBAction func btnMapTap(_ sender: UIButton) {

    sender.isUserInteractionEnabled = false

    //put here your code 

添加替代方法viewWillDisappear:

override func viewWillDisappear(_ animated: Bool) {
    btnMap.isUserInteractionEnabled = true
}

答案 2 :(得分:1)

使用userInteractionEnable=false来防止双击就像使用火箭发射器杀死一只蜜蜂。

相反,您可以使用myButton.enabled=false。使用此功能,您可以在停用按钮时更改(如果需要)按钮的布局。

答案 3 :(得分:1)

myButton.multipleTouchEnabled = NO;

答案 4 :(得分:1)

使用此代码:这是布尔条件

button.ismultipleTouchEnabled = false

答案 5 :(得分:1)

禁用isUserInteractionEnabled或禁用按钮在某些情况下不起作用,如果在下一个控制器中调用了后台API,则推送过程将异步进行。

经过一些工作后,我认为最好采用另一种方法,我在 Objective-C 关闭中找到了完成处理程序 迅速在这里可以很好。

这是我在Objective c中使用的示例:

worksheet = workbook.get_sheet_by_name('Transaction Pivots')

这是方法说明:

 -(void)didSettingClick:(id) sender
{
    if (!isPushInProcess) {
             isPushInProcess = YES;
            SettingVC *settings = [[SettingVC alloc] initWithcomplition:^{
               isPushInProcess = NO;
            }];
            [self.navigationController pushViewController:settings animated:YES];
           }

}

内部viewDidAppear()

dispatch_block_t pushComplition;

-(instancetype) initWithcomplition:(dispatch_block_t)complition{
    self = [super init];
    if (self) {
        pushComplition = complition;
    }
    return self;
}

迅速使用defer关键字也是个好主意。

希望有帮助!

答案 6 :(得分:0)

当用户第一次点击时,您可以禁用该按钮的userInteraction。

然后会出现新的视图控制器,同时留给新的View Controller调用此

 -(IBAction)btnAction:(UIButton *)sender {
   sender.userInteractionEnabled=NO;
  //do your code
  }

如果它移动到另一个视图,则调用低于一个

 -(void)viewWillDisappear {
  buttonName.userInteractionEnabled=YES;
 }

如果不从目前的观点移动 你可以打电话

  sender.userInteractionEnabled=YES;

在btnAction方法结束时。

它肯定会起作用。

答案 7 :(得分:0)

Swift 中,您还可以使用defer关键字来执行代码块,该代码块仅在执行离开当前作用域时才会执行。

@IBAction func btnAction(_ sender: UIButton) {
    sender.isUserInteractionEnabled = false
    defer {
        sender.isUserInteractionEnabled = true
    }
    // rest of your code goes here
}

注意:仅当“代码的其余部分”不是async时,这才有用,因此执行实际上会离开当前范围。 在异步情况下,您需要在该异步方法的末尾设置isUserInteractionEnabled = true

答案 8 :(得分:0)

我是这样做的

var callInProgress = false


func call(){

   if callInProgress == true{
     return
   }

   callInProgress = true

  //Make it false when your task done

}

在您将callInProgress设置为false之前,不允许用户再调用一次函数

这是唯一起作用的

答案 9 :(得分:0)

似乎在 iOS 14.x 下它会在您点击时自动发生。

我编写了一个带有导航控制器的小型演示应用程序,一个“ViewController”类的控制器,带有一个调用“pushIt”动作的按钮。

(见代码) 我已将 Storyboard ID 设置为单独的控制器为“ColoredVCID”并添加了一个全局计数器,只是为了查看...

很长的路短:它似乎正常工作。

//  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)
        }
    
    }

过去天我通常这样做:

   @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)
    }

如果您的按钮例如调用网络请求...以防止重复调用,那么现在这可能非常有用。

(我添加了一些化妆品来使用 alpha .. 让用户将其视为“已禁用”..)