新进的公司, 新接手的项目, 新的代码, 发现了好多输入框, 但是都没做长度限制........., 一个个限制, 我觉得我会疯掉. 突然想到了神奇的Runtime. 之前有看到过一篇, 使用Runtime 拿到文件的button, 加事件的. 或许是一个思路
经过了一个上午加中午的实验, 终于成功了
直接上代码
#import "UITextField+Length.h"
#import <objc/runtime.h>
@implementation UITextField (Length)
+ (void)load
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method oldMethod = class_getInstanceMethod([self class], @selector(setDelegate:));
Method newMethod = class_getInstanceMethod([self class], @selector(hook_setDelegate:));
method_exchangeImplementations(oldMethod, newMethod);
});
}
#pragma mark - 交换代理方法
- (void)hook_setDelegate:(id<UITextFieldDelegate>)delegate
{
SEL oldSelector = @selector(textField:shouldChangeCharactersInRange:replacementString:);
SEL newSelector = @selector(hook_textField:shouldChangeCharactersInRange:replacementString:);
Method oldMethod_del = class_getInstanceMethod([delegate class], oldSelector);
Method oldMethod_self = class_getInstanceMethod([self class], oldSelector);
Method newMethod = class_getInstanceMethod([self class], newSelector);
// 若未实现代理方法,则先添加代理方法
BOOL isSuccess = class_addMethod([delegate class], oldSelector, class_getMethodImplementation([self class], newSelector), method_getTypeEncoding(newMethod));
if (isSuccess) {
class_replaceMethod([delegate class], newSelector, class_getMethodImplementation([self class], oldSelector), method_getTypeEncoding(oldMethod_self));
} else {
// 若已实现代理方法,则添加 hook 方法并进行交换
BOOL isVictory = class_addMethod([delegate class], newSelector, class_getMethodImplementation([delegate class], oldSelector), method_getTypeEncoding(oldMethod_del));
if (isVictory) {
class_replaceMethod([delegate class], oldSelector, class_getMethodImplementation([self class], newSelector), method_getTypeEncoding(newMethod));
}
}
[self hook_setDelegate:delegate];
}
#pragma mark - 交换的方法
- (BOOL)hook_textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if (textField.keyboardType == UIKeyboardTypeNumberPad ) {
if (textField.text.length > 10) {
textField.text = [textField.text substringToIndex:10];
return [self hook_textField:textField shouldChangeCharactersInRange:range replacementString:string];
}
}
if (textField.text.length > 30) {
textField.text = [textField.text substringToIndex:30];
return [self hook_textField:textField shouldChangeCharactersInRange:range replacementString:string];
}
return YES;
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
return [self textField:textField shouldChangeCharactersInRange:range replacementString:string];
}
@end