监听UITextField的删除事件(完善)

本文对原文内容进行修改
原文 //www.greatytc.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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容