Skip to content

Instantly share code, notes, and snippets.

@odrobnik
Created June 4, 2012 12:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odrobnik/2867970 to your computer and use it in GitHub Desktop.
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?
#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();
}
}
}
@odrobnik
Copy link
Author

odrobnik commented Jun 4, 2012

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment