Created
June 4, 2012 12:11
-
-
Save odrobnik/2867970 to your computer and use it in GitHub Desktop.
Riddle: why is the parameter UIView in one place and UITapGestureRecognizer in another?
This file contains hidden or 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
#import "UIView+DTActionHandlers.h" | |
#import <objc/runtime.h> | |
char * const kDTActionHandlerTapBlockKey = "DTActionHandlerTapBlockKey"; | |
char * const kDTActionHandlerTapGestureKey = "DTActionHandlerTapGestureKey"; | |
char * const kDTActionHandlerLongPressBlockKey = "DTActionHandlerLongPressBlockKey"; | |
char * const kDTActionHandlerLongPressGestureKey = "DTActionHandlerLongPressGestureKey"; | |
@implementation UIView (DTActionHandlers) | |
- (void)setTapActionWithBlock:(void (^)(void))block | |
{ | |
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(___DTHandleTapAction:)]; | |
[self addGestureRecognizer:gesture]; | |
objc_setAssociatedObject(self, kDTActionHandlerTapGestureKey, gesture, OBJC_ASSOCIATION_RETAIN); | |
// dynamically add the handler method | |
void(^handler)(UIView *) = ^(UIView *sender) { | |
UIGestureRecognizer *gesture = objc_getAssociatedObject(sender, kDTActionHandlerTapGestureKey); | |
if (gesture.state == UIGestureRecognizerStateRecognized) | |
{ | |
void(^action)(void) = objc_getAssociatedObject(sender, kDTActionHandlerTapBlockKey); | |
if (action) | |
{ | |
action(); | |
} | |
} | |
}; | |
IMP myIMP = imp_implementationWithBlock((__bridge void *)handler); | |
SEL selector = NSSelectorFromString(@"___DTHandleTapAction:"); | |
class_addMethod([self class], selector, myIMP, "v@:"); | |
objc_setAssociatedObject(self, kDTActionHandlerTapBlockKey, block, OBJC_ASSOCIATION_COPY); | |
} | |
- (void)___DTHandleTapAction:(UITapGestureRecognizer *)gesture | |
{ | |
if (gesture.state == UIGestureRecognizerStateRecognized) | |
{ | |
void(^action)(void) = objc_getAssociatedObject(gesture, kDTActionHandlerTapBlockKey); | |
if (action) | |
{ | |
action(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I found through testing that if I add the method dynamically then the gesture recognizer passes the view to it where it is attached. The normal behavior is to get a pointer to the recognizer itself as parameter. Why is that?