内容简介:在使用UITextField的过程中,不免会有限制字符个数,字符输入规则的需求。一般情况下,会有如下两种方法:依然是利用block回调,不过实现方式有点不同。对于UITextField用来做字符限制最好的方法就是使用
在使用UITextField的过程中,不免会有限制字符个数,字符输入规则的需求。一般情况下,会有如下两种方法:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
BNTextField-Limit 的方法
依然是利用block回调,不过实现方式有点不同。
[testField limitCondition:^BOOL(NSString *inputStr){
return ![testField.text isEqualToString:@"111"];
} action:^{
NSLog(@"limit action");
}];
Or
[testField limitNums:3 action:^{
NSLog(@"num limit action");
}];
复制代码
BNTextField-Limit 的实现策略
对于UITextField用来做字符限制最好的方法就是使用 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
这个代理方法,我们通过判断string来确定UITextField是否响应输入。
接下来就是如何封装好代理回调的这个过程了这里我借鉴了 facebook /** KVOController **的思想,创建一个中间管理者,来接管代理方法。 不过需要考虑几个问题:
- 代理释放的问题
- 多个条件约束
- 如何不影响其他代理方法
实现过程:
- 首先,我们假定,AController内实现了UITextField的delegate,我们先把delegate的身份接管过来,实现 偷梁换柱 。
// self 即UITextField 这里这是一个分类方法 self.delegate = UITextFieldDelegateManager.sharedInstance 复制代码
- UITextFieldDelegateManager为中间管理类, keyCode:
@interface UITextFieldDelegateManager : NSObject<UITextFieldDelegate> {
NSMapTable<id,_LimitInfo *> *_infos;
}
+ (instancetype)sharedInstance;
- (void)addLimitNums:(NSInteger)num key:(id)key target:(id<UITextFieldDelegate>)target action:(void(^)(void))action;
@end
复制代码
@interface _LimitInfo : NSObject @property(nonatomic,assign)NSInteger num; @property(nonatomic,weak)id<UITextFieldDelegate> pinocchio; @end 复制代码
这时,我们的UITextField的delegate成为了UITextFieldDelegateManager,这样我们就“截获”了AController的delgate身份。 而这里有一个问题,那就是AController的UITextFieldDelegate内所有方法会失效,这个问题,我们稍后再说。
-
实现
- (void)addLimitNums:(NSInteger)num key:(id)key target:(id<UITextFieldDelegate>)target action:(void(^)(void))action;
_LimitInfo *info = [_infos objectForKey:key];
if (!info) {
info = [_LimitInfo new];
info.pinocchio = target;
}
info.condition = condition;
[info setConditionAction:action];
[_infos setObject:info forKey:key];
复制代码
这里Key是UITextField当前实例对象,target是AController,我们把这两者映射进一个NSMapTable中,NSMapTable的弱引用会使我们不用担心循环引用。其作用和字典一样。
同时,也解决了多个条件约束的问题。
而_LimitInfo只是对AController的一个包装,到这时,我们的AController已经被架空了,成为了一个受我们摆布的傀儡:smirk:,pinocchio保存了AController的实例。
- 接下来就简单了,将UITextFieldDelegate在UITextFieldDelegateManager中全部实现出来 主要是我们的shouldChangeCharactersInRange代理方法
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
BOOL checkInLimit = NO;
_LimitInfo *info = [self safeReadForKey:textField];
if (info.condition && !info.condition(string) && string.length > 0) {
info.conditionAction();
checkInLimit = YES;
}
if (info.num != 0) {
if (info && textField.text.length == info.num && string.length > 0) {
info.action();
checkInLimit = YES;
}
}
if (checkInLimit) {
return NO;
}
if (!info.pinocchio) {
return YES;
}
return [info.pinocchio textField:textField shouldChangeCharactersInRange:range replacementString:string];
}
复制代码
其他方法类似,具体可以参见源码
不过这里还要注意我们刚刚提到的问题,通过我们的pinocchio return [info.pinocchio textField:textField shouldChangeCharactersInRange:range replacementString:string];
来控制原本逻辑,不然delegate就失效了
至于代理释放的问题,我是通过runtime hook UITextField的removeFromSuperview方法,在这个方法调用的时候,将pinocchio重新设置回UITextField的delegate,同时移除缓存。
_LimitInfo* info = [_infos objectForKey:key]; ((UITextField*)key).delegate = info.pinocchio; [_infos removeObjectForKey:key]; 复制代码
- 至此,一个基于 facebook / KVOController 思想的小 工具 就出炉了,虽然简单,但是需要这种思想还是比较巧妙的。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- php如何实现session,自己实现session,laravel如何实现session
- AOP如何实现及实现原理
- webpack 实现 HMR 及其实现原理
- Docker实现原理之 - OverlayFS实现原理
- 为什么实现 .NET 的 ICollection 集合时需要实现 SyncRoot 属性?如何正确实现这个属性?
- 自己实现集合框架(十):顺序栈的实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Web Data Mining
Bing Liu / Springer / 2011-6-26 / CAD 61.50
Web mining aims to discover useful information and knowledge from Web hyperlinks, page contents, and usage data. Although Web mining uses many conventional data mining techniques, it is not purely an ......一起来看看 《Web Data Mining》 这本书的介绍吧!
随机密码生成器
多种字符组合密码
html转js在线工具
html转js在线工具