Protothomas
Protothomas

Reputation: 79

Disable user interaction with different ui elements immediately after tapping on a button

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?

Upvotes: 0

Views: 1226

Answers (1)

ravron
ravron

Reputation: 11211

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.

Upvotes: 2

Related Questions