0

I need to disable all user interactions with other ui elements immediately after the user taps on a button. I want to prevent the user from triggering multiple actions at once, for example pressing a button and tap on an element in a collection view or a tap on a UIBackBarButton.

So as an example I created a UIBarButtonItem that calls this method, that disables user interactions of self.view and the UIBarButtonItems and re-enables them again after 1 second:

- (void)buttonPressed:(id)sender
{
    self.view.userInteractionEnabled = NO;
    self.navigationItem.backBarButtonItem.enabled = NO;
    self.navigationItem.rightBarButtonItem.enabled = NO;

// ... show an alert view

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        self.view.userInteractionEnabled = YES;
        self.navigationItem.backBarButtonItem.enabled = YES;
        self.navigationItem.rightBarButtonItem.enabled = YES;
    });

}

The problem is, that if I tap this button and for example the back button almost simultaneously, it shows the alert view and pops the current viewController. I assume, that it waits a few milliseconds to determine, if this event is a single touch or multiple touch event (e.g. double tap), but I couldn't figure out how to handle this.

What can I do to disable the user interactions immediately after the user tapped this button?

Protothomas
  • 79
  • 10
  • 1
    I believe your action is on `UIControlEventTouchUpInside `. Make it to `UIControlEventTouchDown ` – Fahim Parkar Dec 10 '14 at 12:40
  • Hi, thanks for your answer. I made a little mistake in the description of example. I actually created a UIBarButtonItem to call this method. And this is not an inheritance of UIControl, so there is no way to change the UIControlEvents. I updated the question. – Protothomas Dec 10 '14 at 13:02
  • my answer will still remain same. create [uibarbutton as uibutton as shown here](http://stackoverflow.com/a/16603533/1066828). now for uibutton, make event to UIControlEventTouchDown. You are done :) – Fahim Parkar Dec 10 '14 at 13:26
  • I think the problem is that `self.navigationItem.backBarButtonItem` doesn't has an action or target with it, it is just for appearance, you should create a `self.navigationItem.leftBarButtonItem` and disable it when you touch the button. – gabbler Dec 10 '14 at 14:07

1 Answers1

2

The appearance of the UIAlertView should prevent further user interaction. You're saying, though, that there is a very short window ("a few milliseconds" is a tiny delay as far as the user perceives it) in which the user could touch up on some other button, and cause weird behavior. Ok, without testing, I'll just take that as true.

One rather brute-force way to do this would be to set exclusiveTouch to YES on the button in question. See the Event Handling Guide for a full explanation. Basically, when a view whose exclusiveTouch property is YES is tracking a touch, no other views may track touches. Similarly, such a view may not begin tracking touches unless no other views are tracking touches.

A sidenote: I think you're using dispatch_after to get a block onto the main queue. Typically you'd just use dispatch_async if your intention is to put something on the main queue for immediate execution.

EDIT: When this question was asked, it did not specify the use of UIBarButtonItem. This answer will only work with UIView or a descendant thereof.

ravron
  • 11,014
  • 2
  • 39
  • 66