简体   繁体   中英

UIButton+Category implementation override other UIButton's touch event

I am using a opensource implementation of UIButton with extension so it is draggable.

Here's the header of this UIButton+NMCategory file:

#import <UIKit/UIKit.h>

@interface UIButton (NMCategory)

@property(nonatomic,assign,getter = isDragEnable)   BOOL dragEnable;
@property(nonatomic,assign,getter = isAdsorbEnable) BOOL adsorbEnable;

@end

and in it's implementation, it implements the onTouchesBegin , onTouchesMoved and onTouchesEnd interfaces, which all functioning OK and this button became draggable.

However, in the rest part of my project, there's another implementation of a draggable button been used. Here's the header of it:

@interface SEFilterKnob : UIButton

@end

And below is how it is been used:

[knob addTarget:self action:@selector(MyTouchDown:withEvent:) forControlEvents:UIControlEventTouchDown];
[knob addTarget:self action:@selector(MyTouchUp:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside];
[knob addTarget:self action:@selector(MyTouchMove:withEvent:) forControlEvents: UIControlEventTouchDragOutside | UIControlEventTouchDragInside];

When I apply the UIButton+NMCategory implementation to the whole project, the SEFilterKnob draggable button stopped working and I saw it's touch events are all routed to the UIButton+NMCategory touch event implementation. (its own selectors are not being called)

I am not familiar with Obj-C's category feature, can someone please help explain why this could happen? Thanks!

Unfortunately, you can't combine the two. Also, be very mindful about the destructive effects of the categories in Obj-C.

They modify ALL instances of the class and I'd definitely opted out for the good-old subclass. It's the safest and the right decision. Especially if you're experiencing conflicts.

In a category you normally tend to overwrite current methods.

From developer.apple.com : "When a category overrides an inherited method, the method in the category can, as usual, invoke the inherited implementation via a message to super. However, if a category overrides a method that already existed in the category's class, there is no way to invoke the original implementation"

If you like to call your old/overwritten method, you should try swizzling which is a powerful obj-c feature (and it's not a hack!).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM