我正在尝试找到一种方法来使用按钮按下,不是从响应链本身,而是从绑定(bind)到该按钮的其他操作方法。我找遍了这个解决方案,但一直找不到。
例如,假设我为一个事件设置了一个带有选择器的按钮:
[button addTarget:self action:@selector(handler1:) forControlEvents:UIControlEventTouchUpInside];
然后在代码的后面,根据具体的应用程序情况,我想为同一个控件事件添加另一个事件处理程序到同一个按钮:
[button addTarget:self action:@selector(handler2:) forControlEvents:UIControlEventTouchUpInside];
这很好用,这两个事件确实被调用了。但我的问题是,在不从按钮中删除 handler1 的情况下,我怎样才能做到在调用 handler2 时事件被“消耗掉”并且 handler1 不会被调用?
我遇到这种情况的原因是我希望我的应用程序进入教程模式,在教程模式下我动态地将新事件绑定(bind)到按钮。本教程将指示用户点击某个按钮,但我希望屏幕上其他按钮上的点击事件被忽略,基本上是强制用户点击请求的按钮以继续本教程。因此,当用户进入教程时,每个按钮都会添加一个新的 TouchUpInside 处理程序。我希望首先调用这个新处理程序并阻止执行原始处理程序。
我已经能够首先通过在 NSSet
中获取所有原始事件来实现它被调用,然后为所有现有的调用 [button removeTarget...]
事件。然后我添加我的动态事件,然后重新添加集合中的所有原始事件。这在调试器中起作用,以表明我的动态事件确实首先被调用。
- 例如:
- handler1 将在按下时执行某些操作(按钮的默认处理程序)
- handler2 是动态添加的,将与教程 Controller 通信,“消耗”点击事件(阻止 handler1 执行)。
当不处于教程模式时,我希望 handler1 仍然执行它应该执行的操作,但如果 handler2 存在,我希望该方法运行,然后阻止 handler1 被调用。我不能从按钮中丢失 handler1,因为当教程结束时,我希望应用程序按预期工作。此外,在某些情况下,我可能仍希望调用 handler1。
那么,是否有可能消费一个事件并阻止其他相关事件触发?
我曾尝试在 handler2 中执行 [button resignFirstResponder]
,但这似乎不起作用。它仍然调用原始按钮事件处理程序。
最佳答案
基于@danielquokka关于覆盖方法 sendActionsForControlEvents:
的想法,我将 UIButton 子类化并添加以下代码。它工作正常。触发事件后,它将阻止 UI 事件 0.5 秒。
- (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
{
[super sendAction:action to:target forEvent:event];
self.userInteractionEnabled = NO;
///! After handle UIEvent, block this button UI events for a while.
[self performSelector:@selector(delayEnable) withObject:nil afterDelay:0.5];
}
- (void)delayEnable
{
self.userInteractionEnabled = YES;
}
更新
另一种忽略 UI 事件的方法是通过 [[UIApplication sharedApplication] beginIgnoringInteractionEvents]
和 [[UIApplication sharedApplication] endIgnoringInteractionEvents]
。
beginIgnoringInteractionEvents
和 endIgnoringInteractionEvents
将阻止应用程序的所有触摸事件,直到调用 endIgnoringInteractionEvents
。
关于ios - 具有多个操作的 UIButton : How to prevent other actions from firing,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26169752/