防止多次点击同一个 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-C 或 Closure 中找到了 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的主要内容,如果未能解决你的问题,请参考以下文章