具有多个动作的 UIButton:如何防止其他动作触发 [英] UIButton with multiple actions: How to prevent other actions from firing

查看:19
本文介绍了具有多个动作的 UIButton:如何防止其他动作触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试找到一种方法来使用按钮按下,而不是来自响应链本身,而是来自绑定到该按钮的其他操作方法.我已经到处寻找这个解决方案,但一直找不到.

I'm trying to find a way to consume a button press, not from the response chain per se, but from other action methods bound to that button. I've looked all over for this solution and have been unable to find it.

例如,假设我为一个事件设置了一个带有选择器的按钮:

For example, lets say I set up a button with a selector for an event:

[button addTarget:self action:@selector(handler1:) forControlEvents:UIControlEventTouchUpInside];

然后在后面的代码中,根据具体的应用情况我想为同一个按钮添加同一个控件事件的另一个事件处理程序:

Then later in the code, based on specific app circumstances I want to add another event handler for the same control event to the same button:

[button addTarget:self action:@selector(handler2:) forControlEvents:UIControlEventTouchUpInside];

这很好用,这两个事件都确实被调用了.但我的问题是,在不从按钮中删除 handler1 的情况下,我怎样才能做到在调用 handler2 时,事件被消耗"并且 handler1 不会被调用?

This works fine, both events are indeed called. But my question is, without removing handler1 from the button, how can I make it so that when handler2 is called, the event is "consumed" and handler1 does not get called?

我遇到这种情况的原因是我希望我的应用程序进入教程模式,在教程模式下我动态地将新事件绑定到按钮.本教程将指示用户点击某个按钮,但我希​​望忽略屏幕上其他按钮上的点击事件,基本上是强制用户点击请求的按钮以继续教程.因此,当用户进入教程时,每个按钮都会添加一个新的 TouchUpInside 处理程序.我希望首先调用这个新的处理程序并阻止原始处理程序执行.

The reason I have such a circumstance is that I want my app to go into a tutorial mode, where I dynamically bind new events to buttons while in the tutorial mode. The tutorial will instruct the user to tap a certain button, but I want the tap events on the other buttons on the screen to be ignored, basically forcing the user to tap the requested button to continue with the tutorial. So every button gets a new TouchUpInside handler added when the user enters the tutorial. I want this new handler to be called first and block the original handler from executing.

我已经能够通过在 NSSet 中获取所有原始事件,然后为所有现有事件调用 [button removeTarget...] 来实现它被调用事件.然后我添加我的动态事件,然后重新添加集合中的所有原始事件.这在调试器中起作用,表明我的动态事件确实首先被调用.

I have been able to achieve it being called first by getting all the original events in an NSSet, then calling [button removeTarget...] for all the existing events. Then I add my dynamic event and then re-add all the original events from the set. This works in the debugger to show that my dynamic event is indeed called first.

  • 例如:
  • handler1 在按下时会做一些事情(按钮的默认处理程序)
  • handler2 是动态添加的,它将与教程控制器通信,消耗"点击事件(阻止 handler1 执行).

当不在教程模式下时,我希望 handler1 仍然做它应该做的事情,但如果 handler2 存在,我希望该方法运行,然后阻止 handler1 被调用.我不能从按钮中丢失 handler1,因为当教程结束时,我希望应用程序按预期工作.此外,我可能在某些情况下仍希望调用 handler1.

When not in tutorial mode, I want handler1 to still do what it's supposed to do, but if handler2 exists I want that method to run, then prevent handler1 from being called. I can't lose handler1 from the button because when the tutorial ends, I'd want the app to work as intended. In addition, I may have certain cases where I still want handler1 to be called.

那么,是否可以消费一个事件并阻止其他相关事件触发?

So, is it possible to consume an event and keep other related events from firing?

我曾尝试在 handler2 中执行 [button resignFirstResponder],但这似乎不起作用.它仍然调用原来的按钮事件处理程序.

I have tried doing a [button resignFirstResponder] in handler2, but that doesn't seem to work. It still calls the original button event handler.

推荐答案

基于 @danielquokka 关于覆盖方法 sendActionsForControlEvents:,我继承 UIButton 并添加以下代码.它工作正常.触发事件后,会阻塞 UI 事件 0.5 秒.

Based on the @danielquokka idea about override the method sendActionsForControlEvents:, I subclass UIButton and add following codes. It works fine. After firing event, it will block UI events for 0.5 seconds.

- (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].

beginIgnoringInteractionEventsendIgnoringInteractionEvents 将阻止应用程序的所有触摸事件,直到调用 endIgnoringInteractionEvents.

beginIgnoringInteractionEvents and endIgnoringInteractionEvents will block all touch events for the Application until endIgnoringInteractionEvents called.

这篇关于具有多个动作的 UIButton:如何防止其他动作触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆