限制 UITextField 输入长度
2015-06-24 18:46
549 查看
限制 UITextField 输入长度
标签(空格分隔): UITextFieldUITextField 是 iOS 中最常用的组件之一。关于它也有各种各样的需求,这些需求是它本身没有提供相应的API的。限制输入框文本长度是常见的需求,UITextField 本身也并没有为此提供API。本文尝试给其加入这个功能。
1、通过 delegate 来实现(不推荐)
限制 UITextField 的输入字数,首先想到的是UITextFieldDelegate,通过实现这个协议来实现需求:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string; // 返回 NO 就不会改变文本
OK,那咱们来试试看:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *beString = [textField.text stringByReplacingCharactersInRange:range withString:string]; if ([beString length] > 20) { textField.text = [beString substringToIndex:20]; return NO; } return YES; }
1. 先计算出在用户输入这段文字会产生的新文本:beString。
2. 再判断beString长度是否符合长度限制(这里为20)。
3. 如果符合则返回YES,否则返回NO。
OK,这么做实现了咱们的需求,在各种输入法、中英文下都运行无误。这就完了?NO!
我们来说说这种解决文案的不足之处:
1. 代码量太多。看看上面的例子,这还是只是一个输入框,如果有2个、3个、N个。。。 (这得重新考虑一下你们的需求了)
2. 给每一个要限制长度的输入框都得这么写,想想也是醉了(没错,偶以前也是这么干的)。
2、继承 UITextField来实现(不推荐)
继承 UITextField ,覆写setText:方法应该是可以实现的(偶没做过)。但基于无数先辈们得出的经验:组合先于继承。在这里用继承也是有点小问题的:假设咱们子类名字为
NLUITextFieldTextLimit,那
NITextField(nimbus 框架中的一个类) 对象也就无法享受到这一服务了。
3、分类添加属性来实现(推荐)
如果能用分类,添加一个属性来实现这个需求得多爽呀,在UITextField中定义一个属性就好了。咱们来研究一下
UITextField看看有没有可能。
@interface UITextField : UIControl ...
UITextField是继承自
UIControl的,那它可以监听自身的事件咯!Good!我们只要得知其输入文本变化后,再判断长度是否符合需求。看看咱们的代码:
// .h file @interface UITextField (NLLimit) @property (assign, nonatomic) NSUInteger nl_maxLength; @end // .m file #import <objc/runtime.h> @implementation UITextField (NLLimit) static void *nlLimitMaxLengthKey = &nlLimitMaxLengthKey; - (void)setNl_maxLength:(NSUInteger)nl_maxLength { objc_setAssociatedObject(self, nlLimitMaxLengthKey, @(nl_maxLength), OBJC_ASSOCIATION_COPY); /** * 监控自身文本变化 */ if (nl_maxLength > 0) { [self addTarget:self action:@selector(_nl_valueChanged:) forControlEvents:UIControlEventAllEditingEvents]; } else { [self removeTarget:self action:@selector(_nl_valueChanged:) forControlEvents:UIControlEventAllEditingEvents]; } } - (NSUInteger)nl_maxLength { return [objc_getAssociatedObject(self, nlLimitMaxLengthKey) unsignedIntegerValue]; } #pragma mark - private - (void)_nl_valueChanged:(UITextField *)textField { /** * 在文本变化后判断文本长度是否符合需求 */ if (self.nl_maxLength == 0) return; if ([textField.text length] <= self.nl_maxLength) return; NSString *subString = [textField.text substringToIndex:self.nl_maxLength]; dispatch_async(dispatch_get_main_queue(), ^{ textField.text = subString; [textField sendActionsForControlEvents:UIControlEventEditingChanged]; }); } @end
代码在这里。
嗯,简单直接,就是它了!
4、限制 UITextView 输入长度
在UITextField中我们推荐的限制文本长度的方式是通过分类中添加属性来做到的,其本质是监控自身的输入文本变化,再判断长度是否符合需求。那
UITextView是不是也可以这么做呢?
@interface UITextView : UIScrollView
可惜的是,正如上面所示,
UITextView是
UIScrollView的子类,并非如
UITextField那般是
UIControl的子类,也就是说
UITextView无法像
UITextField那样通过监控自身的来达到限制的目的了。
不过好在我们在 UITextView 的说明文档中看到了几个通知:
NSString * const UITextViewTextDidBeginEditingNotification; NSString * const UITextViewTextDidChangeNotification; NSString * const UITextViewTextDidEndEditingNotification;
通过这几个通知也可以得知任何一个
UITextView输入文本的变化了。咱们可以整个辅助类来做到这一点。代码就不贴出来了,你也可以自己试验一下,想看完整代码,在这里。
相关文章推荐
- 【Xamarin 】MonoTouch - UIImageView响应点击事件
- UI--学习模仿QQ未读提醒拖拽删除
- easyui combogrid onChanage 问题
- Permutation Sequence算法详解
- 下拉选单(droplist)交互设计-控制另一个下拉选单
- [POJ 3498] March of the Penguins
- 视差滚动特效图片滑块-Sequence.js
- Java GUI程序设计的初步上
- [SoapUI] 如何让某个步骤的Assertion失败之后继续执行后面的步骤
- 如何去做UI适配
- Programming Quick Start Guide翻译
- UITextField输入框中是否有个叉号(用于一次性删除输入框中的内容)
- SylixOS JobQueue 简介
- 如何诊断RAC系统中的'gc cr multi block request'?
- UI框架收集
- UI框架收集
- UIViewContentMode各类型效果
- N-Queens II
- KVC中setValuesForKeysWithDictionary:
- 51.N-Queens&n皇后问题