Ios 如何确保仅运行一个操作来响应用户输入?

Ios 如何确保仅运行一个操作来响应用户输入?,ios,cocoa-touch,Ios,Cocoa Touch,假设一个应用程序有两个按钮,每个按钮启动一个动画(例如,一个按钮或其他标准序列或自定义动画)。如果用户“同时”按下两个按钮,如何阻止两个动画同时发生?首先,我试着: [[viewController view] setUserInteractionEnabled:NO]; 但这并不能解决问题。(可能userInteractionEnabled没有立即级联到子视图?) 然后我试着: [[UIApplication sharedApplication] beginIgnoringInteracti

假设一个应用程序有两个按钮,每个按钮启动一个动画(例如,一个按钮或其他标准序列或自定义动画)。如果用户“同时”按下两个按钮,如何阻止两个动画同时发生?首先,我试着:

[[viewController view] setUserInteractionEnabled:NO];
但这并不能解决问题。(可能
userInteractionEnabled
没有立即级联到子视图?)

然后我试着:

[[UIApplication sharedApplication] beginIgnoringInteractionEvents];
这确实解决了问题,除非你很快地一个接一个地按下两个按钮(基本上是用两个手指同时按下两个按钮),然后两个动画都会出现,这会给我的应用程序带来问题。可能在调用我要运行的代码
-beginIgnoringInteractionEvents
之前已经触发了这两个事件

立即停止任何其他tap事件的可靠方法是什么?或者清除那些已经开始的。我的应用程序到处都有这个问题——按下两个按钮(或点击表格单元格等)会很快触发两个事件,并搞乱动画


有什么想法吗?在iOS应用程序中,人们如何解决这个问题?

在iOS中,触摸处理是异步进行的,以确保设备响应良好。这意味着处理程序可能会在运行之前排队,这就是为什么您对
beginIgnoringInteractionEvents
的调用被忽略的原因

最简单的解决方案是简单地创建一个全局变量,使交互成为独占的

@interface UIApplicaiton(AnimationsInProgress)

- (BOOL)isAnimationInProgress;
- (void)setAnimationInProgress:(BOOL)value;

@end
以及实施:

@implementation UIApplication(AnimationsInProgress)
{
    BOOL _isAnimationInProgress;
}

- (BOOL)isAnimationInProgress {
    return _isAnimationInProgress;
}

- (void)setAnimationInProgress:(BOOL)value {
    _isAnimationInProgress = value;
}
在动画动作的顶部,您可以像使用
beginIgnoringInteractionEvents
一样使用它:

if ([[UIApplication sharedApplication] isAnimationInProgress)
    return;
[[UIApplication sharedApplication] setAnimationInProgress:YES];

[UIView animate .... completion:^{
    [[UIApplication sharedApplication] setAnimationInProgress:NO];
}];

由于不存在类似于触摸事件和
BeginIngnoringInteractionEvents
的竞态条件,这将符合您的目的。

为什么不添加类似isAnimating的属性,并在按下按钮后和动画前检查其状态?单击按钮检查是否有动画,如果发现动画,请停止该动画并开始新的动画。感谢您的及时回复,但我的应用程序中有很多动画,包括标准推/弹出片段等。因此,我必须具有某种全局isAnimating属性,甚至在我的所有标准片段中设置它!(这很难做到,因为动画完成后必须取消设置)。一定有更好的办法吗?好的,那很有帮助,谢谢。但是标准的iOS segues呢。我想我可以截取prepareForSegue并调用SetAnimationProgress,但我认为没有简单可靠的方法知道segue何时完成。对于segue,请在视图控制器本身中跟踪它,在
prepareForSegue
中设置一个状态布尔值,并在
viewdideappear
中重置它。但我不确定它是否100%可靠,viewdideappear将始终与每个prepareForSegue配对。如果有任何东西失去同步,我将被留下一个死掉的应用程序(动画被阻止)。(还要感谢zoul整理了我的问题:)