lombax85/FLCodeInjector

Suggestion about swizzling method like touchesBegan

bestswifter opened this issue · 1 comments

Inspired from this blog: The Right Way to Swizzle in Objective-C

I met the same problem when trying to swizzle touchesBegan method of UIView. My solution is using IMP directly.

static IMP __original_TouchesBegan_Method_Imp;

+ (void)load {
    Method touchesBegan = class_getInstanceMethod([UIView class], @selector(touchesBegan:withEvent:));
    Method yoga_touchesBegan = class_getInstanceMethod([UIView class], @selector(yoga_touchesBegan:withEvent:));
    __original_TouchesBegan_Method_Imp = method_getImplementation(touchesBegan);
    
    method_exchangeImplementations(touchesBegan, yoga_touchesBegan);
}
- (void)yoga_touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSLog(@"touches Ended, self = %@", self);
    if ([NSStringFromClass([self class]) hasPrefix:@"Yoga"]) {
          // Your logic here
    }
    else {
        void (*functionPointer)(id, SEL, NSSet<UITouch *> *, UIEvent *) = (void (*)(id, SEL, NSSet<UITouch *> *, UIEvent *))__original_TouchesEnded_Method_Imp;
        functionPointer(self, _cmd, touches, event);
    }
}

Nice! Thx for the post. I ended up with the following category based on your approach.

static IMP __original_TouchesBegan_Method_Imp;

@implementation UIView (Touch)

+ (void)load {
    Method touchesBegan = class_getInstanceMethod([UIView class], @selector(touchesBegan:withEvent:));
    Method xxx_touchesBegan = class_getInstanceMethod([UIView class], @selector(xxx_touchesBegan:withEvent:));
    __original_TouchesBegan_Method_Imp = method_getImplementation(touchesBegan);
    method_exchangeImplementations(touchesBegan, xxx_touchesBegan);
}

- (void)xxx_touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    void (*functionPointer)(id, SEL, NSSet<UITouch *> *, UIEvent *) = (void (*)(id, SEL, NSSet<UITouch *> *, UIEvent *))__original_TouchesBegan_Method_Imp;
    functionPointer(self, _cmd, touches, event);
    // Your logic here
}

@end