我正在尝试找到一种方法来消耗按钮,而不是从响应链本身上,而是从绑定到该按钮的其他操作方法中。我到处都在寻找这种解决方案,但一直找不到。
例如,假设我设置了一个带有事件选择器的按钮:
[button addTarget:self action:@selector(handler1:) forControlEvents:UIControlEventTouchUpInside];
然后在代码的后面,根据特定的应用程序情况,我想为同一控件事件向同一按钮添加另一个事件处理程序:
[button addTarget:self action:@selector(handler2:) forControlEvents:UIControlEventTouchUpInside];
这可以正常工作,两个事件确实都被调用了。但是我的问题是,如果不从按钮中删除handler1,我该如何做,以便在调用handler2时,该事件被“消耗”并且不会调用handler1?
我遇到这种情况的原因是,我希望我的应用程序进入教程模式,在此模式下,我将在教程模式下将新事件动态绑定到按钮。本教程将指示用户点击某个按钮,但我希望忽略屏幕上其他按钮上的点击事件,基本上是迫使用户点击所请求的按钮以继续本教程。因此,当用户进入教程时,每个按钮都会获得一个新的TouchUpInside处理程序。我希望首先调用此新处理程序,并阻止原始处理程序执行。
我已经能够通过首先将所有原始事件获取到
NSSet
中,然后为所有现有事件调用[button removeTarget...]
来实现被调用的功能。然后添加动态事件,然后重新添加集合中的所有原始事件。这在调试器中起作用,以表明我的动态事件确实被首先调用。当不在教程模式下时,我希望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
。