防止多次点击同一个 UIButton

Posted

技术标签:

【中文标题】防止多次点击同一个 UIButton【英文标题】:Prevent multiple Tap on the same UIButton 【发布时间】:2016-05-20 08:34:32 【问题描述】:

在我的应用程序中有时我会收到此错误,因为 UI 冻结并且用户多次点击按钮:

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

我试过这个:

How to prevent multiple event on same UIButton in ios?

它就像一个魅力,但如果我的标签栏有超过 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;
    ];

【问题讨论】:

试试这个答案,它适用于单元格中的计时器:***.com/a/22999019/4833705 【参考方案1】:

首先提示,如果您只有按钮调用该选择器,您可以将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; 行。但如果始终使用相同的代码,第一种方法更简单、更快捷。

【讨论】:

【参考方案2】:

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

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

【讨论】:

你能解释一下 userInteractionEnable= false 有什么问题 问题是userInteractionEnable是视图属性,myButton.enabled=false是UIButton属性。因此,您始终应该使用 Apple 为您提供的方式来实现您的目标。 请注意,使用enabled 属性还有其他在这种情况下不需要的副作用。这些是 UI 更改,例如更改按钮上的颜色、文本、图像,以向用户指示按钮已禁用。这意味着当按钮被禁用并在不久之后再次启用时,您会得到一种闪光,这可能会分散/混淆用户的注意力。另外,请不要杀死蜜蜂。 :)【参考方案3】:

Swift中,你也可以使用defer关键字来执行一段代码,该代码块只有在执行离开当前作用域时才会执行。

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

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

【讨论】:

在我点击按钮时显示动画的情况下工作。谢谢【参考方案4】:

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

经过一些工作,我认为最好采用另一种方式,我在 Objective-CClosure 中找到了 Completion handler Swift 在这里可以做得很好。

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

 -(void)didSettingClick:(id) sender

    if (!isPushInProcess) 
             isPushInProcess = YES;
            SettingVC *settings = [[SettingVC alloc] initWithcomplition:^
               isPushInProcess = NO;
            ];
            [self.navigationController pushViewController:settings animated:YES];
           


这里是方法说明:

dispatch_block_t pushComplition;

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

viewDidAppear() 内部

-(void)viewDidAppear:(BOOL)animated

    pushComplition();

在 swift 中使用 defer 关键字也是个好主意。

希望对你有帮助!!!

【讨论】:

【参考方案5】:

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

然后会出现新的视图控制器,同时留给新的视图控制器调用这个

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

如果它正在移动到另一个视图然后调用下面的一个

 -(void)viewWillDisappear 
  buttonName.userInteractionEnabled=YES;
 

如果不从当前视图移动 你可以打电话

  sender.userInteractionEnabled=YES;

在 btnAction 方法的末尾。

它肯定会起作用。

【讨论】:

【参考方案6】:
myButton.multipleTouchEnabled = NO;

【讨论】:

请添加一些您认为这会有所帮助的解释。只贴一行代码是不行的。 它对我不起作用。我仍然可以双击 这行不通,因为问题是关于多次点击,而不是触摸!【参考方案7】:

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

按钮代码:

@IBAction func btnMapTap(_ sender: UIButton) 

    sender.isUserInteractionEnabled = false

    //put here your code 

添加覆盖方法viewWillDisappear:

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

【讨论】:

【参考方案8】:

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

button.ismultipleTouchEnabled = false

【讨论】:

【参考方案9】:

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

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

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

Long way SHORT:它似乎正常工作。

//  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.. 让用户将其视为“已禁用”..)

【讨论】:

【参考方案10】:

我是这样做的

var callInProgress = false


func call()

   if callInProgress == true
     return
   

   callInProgress = true

  //Make it false when your task done


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

这是唯一有效的方法

【讨论】:

以上是关于防止多次点击同一个 UIButton的主要内容,如果未能解决你的问题,请参考以下文章

uniapp 防止重复点击

按钮防止多次点击重复提交的方法

防止用户快速多次点击按钮,响应事件响应多次

如何防止多次点击/点击的默认处理?

如何防止使用php自动多次点击网站?

jQuery click - 防止移动设备中的多次点击