Created
August 8, 2010 09:00
-
-
Save jbenet/513796 to your computer and use it in GitHub Desktop.
UIControl Category to capture and save UIControlEvents flag to its own tag
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The MIT License | |
// | |
// Copyright (c) 2010 Juan Batiz-Benet | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE. | |
//------------------------------------------------------------------------------ | |
// UIControl+CaptureUIControlEvents Category | |
// Author: Juan Batiz-Benet | |
// github gist at: http://gist.github.com/513796 | |
// PROBLEM: upon firing, UIControlEvents are not passed into the target action | |
// assigned to the particular event. This would be useful in order to have only | |
// one action that switches based on the UIControlEvent fired. | |
// | |
// SOLUTION: add a way to store the UIControlEvent triggered in the UIEvent. | |
// | |
// PROBLEM: But we cannot override private APIs, so: | |
// (Worse) solution: have the UIControl store the UIControlEvent last fired. | |
// | |
// The UIControl documentation states that: | |
// > When a user touches the control in a way that corresponds to one or more | |
// > specified events, UIControl sends itself sendActionsForControlEvents:. | |
// > This results in UIControl sending the action to UIApplication in a | |
// > sendAction:to:from:forEvent: message. | |
// | |
// One would think that sendActionsForControlEvents: can be overridden (or | |
// subclassed) to store the flag, but it is not so. It seems that | |
// sendActionsForControlEvents: is mainly there for clients to trigger events | |
// programatically. | |
// | |
// Instead, I had to set up a scheme that registers an action for each control | |
// event that one wants to track. I decided not to track all the events (or in | |
// all UIControls) for performance and ease of use. | |
// | |
// Example Usage: | |
// // (on setup) | |
// UIControlEvents capture = UIControlEventTouchDown; | |
// capture |= UIControlEventTouchDown; | |
// capture |= UIControlEventTouchUpInside; | |
// capture |= UIControlEventTouchUpOutside; | |
// [myControl captureEvents:capture]; | |
// [myControl addTarget:self action:@selector(touch:) forControlEvents:capture]; | |
// | |
// ... | |
// // the target action | |
// - (void) touch:(UIControl *)sender { | |
// UIColor *color = [UIColor clearColor]; | |
// switch (sender.tag) { | |
// case UIControlEventTouchDown: color = [UIColor redColor]; break; | |
// case UIControlEventTouchUpInside: color = [UIColor blueColor]; break; | |
// case UIControlEventTouchUpOutside: color = [UIColor redColor]; break; | |
// } | |
// sender.backgroundColor = color; | |
// } | |
//------------------------------------------------------------------------------ | |
@interface UIControl (CaptureUIControlEvents) | |
- (void) captureEvents:(UIControlEvents)controlEvents; | |
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The MIT License | |
// | |
// Copyright (c) 2010 Juan Batiz-Benet (jbenet@cs.stanford.edu) | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the "Software"), to deal | |
// in the Software without restriction, including without limitation the rights | |
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
// copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
// THE SOFTWARE. | |
// Hmmm one method for each UIControlEvent... so gross. I can hear the purist | |
// inside me screaming: ``You're doing it wrong!'' | |
@implementation UIControl (CaptureUIControlEvents) | |
- (void) captureUIControlEventTouchDown { | |
self.tag = UIControlEventTouchDown; | |
} | |
- (void) captureUIControlEventTouchDownRepeat { | |
self.tag = UIControlEventTouchDownRepeat; | |
} | |
- (void) captureUIControlEventTouchDragInside { | |
self.tag = UIControlEventTouchDragInside; | |
} | |
- (void) captureUIControlEventTouchDragOutside { | |
self.tag = UIControlEventTouchDragOutside; | |
} | |
- (void) captureUIControlEventTouchDragEnter { | |
self.tag = UIControlEventTouchDragEnter; | |
} | |
- (void) captureUIControlEventTouchDragExit { | |
self.tag = UIControlEventTouchDragExit; | |
} | |
- (void) captureUIControlEventTouchUpInside { | |
self.tag = UIControlEventTouchUpInside; | |
} | |
- (void) captureUIControlEventTouchUpOutside { | |
self.tag = UIControlEventTouchUpOutside; | |
} | |
- (void) captureUIControlEventTouchCancel { | |
self.tag = UIControlEventTouchCancel; | |
} | |
- (void) captureUIControlEventValueChanged { | |
self.tag = UIControlEventValueChanged; | |
} | |
- (void) captureUIControlEventEditingDidBegin { | |
self.tag = UIControlEventEditingDidBegin; | |
} | |
- (void) captureUIControlEventEditingChanged { | |
self.tag = UIControlEventEditingChanged; | |
} | |
- (void) captureUIControlEventEditingDidEnd { | |
self.tag = UIControlEventEditingDidEnd; | |
} | |
- (void) captureUIControlEventEditingDidEndOnExit { | |
self.tag = UIControlEventEditingDidEndOnExit; | |
} | |
- (SEL) captureActionForUIControlEvent:(UIControlEvents)controlEvent | |
{ | |
switch (controlEvent) { | |
case UIControlEventTouchDown: | |
return @selector(captureUIControlEventTouchDown); | |
case UIControlEventTouchDownRepeat: | |
return @selector(captureUIControlEventTouchDownRepeat); | |
case UIControlEventTouchDragInside: | |
return @selector(captureUIControlEventTouchDragInside); | |
case UIControlEventTouchDragOutside: | |
return @selector(captureUIControlEventTouchDragOutside); | |
case UIControlEventTouchDragEnter: | |
return @selector(captureUIControlEventTouchDragEnter); | |
case UIControlEventTouchDragExit: | |
return @selector(captureUIControlEventTouchDragExit); | |
case UIControlEventTouchUpInside: | |
return @selector(captureUIControlEventTouchUpInside); | |
case UIControlEventTouchUpOutside: | |
return @selector(captureUIControlEventTouchUpOutside); | |
case UIControlEventTouchCancel: | |
return @selector(captureUIControlEventTouchCancel); | |
case UIControlEventValueChanged: | |
return @selector(captureUIControlEventValueChanged); | |
case UIControlEventEditingDidBegin: | |
return @selector(captureUIControlEventEditingDidBegin); | |
case UIControlEventEditingChanged: | |
return @selector(captureUIControlEventEditingChanged); | |
case UIControlEventEditingDidEnd: | |
return @selector(captureUIControlEventEditingDidEnd); | |
case UIControlEventEditingDidEndOnExit: | |
return @selector(captureUIControlEventEditingDidEndOnExit); | |
} | |
return nil; // shouldnt get here. | |
} | |
- (void) considerCapturing:(UIControlEvents)event | |
forControlEvents:(UIControlEvents)controlEvents | |
{ | |
SEL captureAction = [self captureActionForUIControlEvent:event]; | |
if (captureAction != nil && controlEvents & event) | |
[self addTarget:self action:captureAction forControlEvents:event]; | |
} | |
- (void) captureEvents:(UIControlEvents)events { | |
for (UIControlEvents event = 0x01; event; event <<= 1) | |
[self considerCapturing:event forControlEvents:events]; | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment