Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't UIButton's exclusiveTouch property set to YES by default?

I'm sure there are a lot of reasons why someone would like to have more than one button accept touches at the same time. However, most of us only need one button to be pressed at one time (for navigation, for something to be presented modally, to present a popover, a view, etc.).

So, why would Apple set the exclusiveTouch property of UIButton to NO by default?

like image 943
MiguelB Avatar asked Jun 28 '11 14:06

MiguelB


1 Answers

Very old question, but deserves clarification IMO.

Despite the very misleading method documentation from Apple a view "A" with exclusiveTouch set will prevent other views from receiving events so long as A is processing some event itself (e.g. set a button with exclusiveTouch and put a finger on it, this will prevent other views in the window from being interacted with, but interaction with them will follow the usual pattern once the finger from the exlusiveTouch-item is removed).

Another effect is preventing view A from receiving events as long as some other view is interacted with (keep a button without exclusiveTouch set pressed, and the ones with exclusiveTouch will not be able to receive events as well).

You can still set a button in your view to exclusiveTouch and interact with the others, just not at the same time, as this simple test UIViewController will prove (once the correct bindings in the IB are set for both Outlets and Actions):

#import "FTSViewController.h"

@interface FTSViewController ()
- (IBAction)button1up:(id)sender;
- (IBAction)button2up:(id)sender;
- (IBAction)button1down:(id)sender;
- (IBAction)button2down:(id)sender;

@property (nonatomic, strong) IBOutlet UIButton *button1, *button2;
@end

@implementation FTSViewController

- (IBAction)button1up:(id)sender {
    NSLog(@"Button1 up");
}

- (IBAction)button2up:(id)sender {
    NSLog(@"Button2 up");
}

- (IBAction)button1down:(id)sender {
    NSLog(@"Button1 down");
}

- (IBAction)button2down:(id)sender {
    NSLog(@"Button2 down");
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Guarantees that button 1 will not receive events *unless* it's the only receiver, as well as
    // preventing other views in the hierarchy from receiving touches *as long as button1 is receiving events*
    // IT DOESN'T PREVENT button2 from being pressed as long as no event is being intercepted by button1!!!
    self.button1.exclusiveTouch = YES;
    // This is the default. Set for clarity only
    self.button2.exclusiveTouch = NO;
}
@end

In light of this, the only good reason IMHO for Apple not to set exclusiveTouch to YES for every UIView subclass is that it would have made the implementation of complex gestures a real PITA, including probably some of the gestures we are already accustomed to in composite UIView subclasses (like UIWebView), as setting selected views to exclusiveTouch=NO (like button) is faster than doing a recursive exclusiveTouch=YES on pretty much everything just to enable multitouch.

The drawback of this is that in many cases the counter intuitive behaviour of UIButtons and UITableViewCells (among others...) might introduce weird bugs and make testing more tricky (as it happened to me like... 10 minutes ago? :( ).

Hope it helps

like image 137
Rick77 Avatar answered Nov 15 '22 17:11

Rick77