本文对原文内容进行修改
原文 http://www.jianshu.com/p/d2c2f4aaef0d
项目里有这个需求,需要对删除按钮进行监听,然后做一些自定义的操作。在网上参考了上文的实现方法,写了一个分类,然后前期使用的过程中并未发现Bug,后来在测试的时候,发现了个大Bug
Bug:该分类会监听所有的UITextField 类的deleteBackward函数,如果没有实现该分类的代理方法,结果就是删除按钮点了无效!举个例子:比如我在A界面想要点击删除按钮自定义事件,然后我实现了这个代理,在B页面我就想使用系统的方法,不想自定义,结果。在A页面,确实是实现了该效果,在B页面。。点击删除按钮无效,删不掉字符了。。。
解决方案:
当初始化UITextField的时候,需要使用 method_exchangeImplementations方法来交换自定义的代理和系统的删除事件,然后在自定义的代理里面去判断代理有木有去实现这个方法,如果有的话,就执行代理事件,否则就把系统的方法和自定义的代理替换回来即可。
具体代码如下:
头文件
#import<UIKit/UIKit.h>
@protocol CCTextFieldDelegate
@optional
- (void)textFieldDidDeleteBackward:(UITextField *)textField;
@end
@interface UITextField (Delete)
@property (weak, nonatomic) id delegate;
@end
实现文件
#import ""UITextField+Delete.h""
#import <objc/runtime.h>
@implementation UITextField (Delete)
- (instancetype)init{
if (self=[super init]) {
Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"deleteBackward"));
Method method2 = class_getInstanceMethod([self class], @selector(cc_deleteBackward));
method_exchangeImplementations(method1, method2);
}
return self;
}
- (void)cc_deleteBackward {
if ([self.delegate respondsToSelector:@selector(textFieldDidDeleteBackward:)])
{
id delegate = (id)self.delegate;
[delegate textFieldDidDeleteBackward:self];
}
else{
Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"deleteBackward"));
Method method2 = class_getInstanceMethod([self class], @selector(cc_deleteBackward));
method_exchangeImplementations(method2, method1);
}
}
@end