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];
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?
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.
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.
- For example:
- handler1 will do something when pressed (default handler for the button)
- handler2 is added dynamically and will communicate with the tutorial controller, "consuming" the tap event (preventing handler1 from executing).
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?
I have tried doing a [button resignFirstResponder]
in handler2, but that doesn't seem to work. It still calls the original button event handler.