我试图找到一种方法来按下按钮,而不是从响应链本身,而是从绑定到该按钮的其他动作方法。我已经全神贯注地寻找这个解决方案,而且一直无法找到它。
例如,假设我设置了一个带有事件选择器的按钮:
[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]
,但这似乎不起作用。它仍然调用原始按钮事件处理程序。
答案 0 :(得分:3)
基于覆盖方法sendActionsForControlEvents:
的{{3}}想法,我将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
将阻止应用的所有触摸事件。
答案 1 :(得分:1)
如果您知道应用程序的当前状态(如教程等),那么最好只使用一个handler1。并添加到方法handler1的主体:if(mode == tutorial){tutorial} else {default}。
答案 2 :(得分:1)
您可以向UIButton(或它的子类)添加一个类别,覆盖方法sendActionsForControlEvents:仅为一个目标调用sendAction:to:forEvent:(有关这些方法的描述,请参阅UIControl上的文档)。