iOS 限制UITextField输入字符
开篇
之前做过一个即时通信的项目,需要限制输入框文本的字符个数,当时从网络上搜寻了几个方法,解决了需求,但是网络上的解决办法不是很全面;今天又遇到一个限制搜索框UISearchBar输入字符个数的问题,所以就就想把字符限制这个问题做的完整彻底一点,下面我提出几个问题,然后一一再做解答,看看你在做字符限制的时候有没有遇到同样问题。在提出这几个问题之前,我先介绍几个方法:
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
这个方法是UISearchBar的代理方法,在文本替换之前触发,返回值文BOOL类型,如果返回YES,就替换;反之,则不替换。
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
这个方法是UISearchBar的代理方法,在文本输入完成之后触发,返回值为空(没有返回值)。
我们要做字符限制的工作就在这两个回调方法中实现;姑且,我们把第一个方法称为方法一,第二个方法称之为方法二,下文中提到的方法一和方法二,就代表这两个方法。
PS:解释一下为什么我这里用的是UISearchBar的代理方法,而不是UITextField的代理方法,这是因为我研究时用的就是UISearchBar,因此,在写这篇博客的时候就用了UISearchBar,而不是UITextField;但是,UISeachBar中的输入框其实也是UITextField,所以用UISearchBar做输入字符限制研究也是一样的,最后我会对与UITextField不同的地方做说明。好,现在让我们进入正题。
问题
1. 只在方法一中做字符限制,在中文输入法下做联想输入时会出现什么情况
2. 只在方法一中做字符限制,在粘贴字符到文本框中时会出现什么问题
3. 只在方法二中做字符限制,在中文输入法下,高亮输入时会有什么问题
现在我已经把问题,提出了,下面我们就来解决这些问题。
最简单的限制输入字符的办法就是在统计输入的字符时不区分英文和汉字,如下示例:
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
UITextField* textField = [_searchBar valueForKey:@"_searchField"];
if (textField.text.length > kMaxLength) {
textField.text = [textField.text substringToIndex:kMaxLength];
}
return YES;
}
这样做就会出现我提出的问题1和问题2,当在中文输入法下输入时,选中联想出来的字符是不会调用这个方法的,因此统计字符个数的任务就失败了;同理,粘贴文本时也不会调用这个方法。那如何解决这两个问题呢?就是找一个方法,在这两种情况下仍然可以调用该方法;显然,我提到的方法二就起作用了,现改变如下:
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
UITextField* textField = [_searchBar valueForKey:@"_searchField"];
if (textField.text.length > kMaxLength) {
textField.text = [textField.text substringToIndex:kMaxLength];
}
}
但是,这样做又会出现我上面提到的问题3,在中文输入法下输入字符时,高亮的字符输入不会调用这个方法;因此统计字符输入还是有点小问题。那如何处理才能达到我们的目的呢?现在我把代码做如下更改:
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if (text.length == 0) {
return YES;
}
NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 键盘输入模式
if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写
UITextField* textField = [_searchBar valueForKey:@"_searchField"];
if (textField.text.length > kMaxLength) {
return NO;
}
}
return YES;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
UITextField* textField = [_searchBar valueForKey:@"_searchField"];
if (textField.text.length > kMaxLength) {
textField.text = [textField.text substringToIndex:kMaxLength];
}
}
好,现在提到的三个问题都得到了解决。
拓展
如果统计的字符要区分中英文,那可以这样做:
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
if (text.length == 0) {
return YES;
}
NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 键盘输入模式
if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写
UITextField* textField = [_searchBar valueForKey:@"_searchField"];
if (textField.text.length > kMaxLength) {
return NO;
}
}
return YES;
}
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText {
NSString* text = [self textLength:searchText];
searchBar.text = text;
}
- (NSString* )textLength:(NSString *)text//计算字符串长度
{
int number = 0.0;
for (int index = 0; index < [text length]; index++)
{
NSString *character = [text substringWithRange:NSMakeRange(index, 1)];
if ([character lengthOfBytesUsingEncoding:NSUTF8StringEncoding] == 3) {
number+=2;
} else {
number++;
}
if (kMaxLength == number) {
return [text substringWithRange:NSMakeRange(0, index + 1)];
}
}
return text;
}
这样一个中文就代表两个英文,这个可以根据需要自己更改。
受文章http://blog.sina.com.cn/s/blog_60f977e70101g4gj.html启发,现将- (NSString* )textLength:(NSString *)text方法做一下优化:
- (NSString* )textLength:(NSString *)text//计算字符串长度
{
UITextRange *selectedRange = [_textField markedTextRange];
UITextPosition *position = [_textField positionFromPosition:selectedRange.start offset:0];
if (!posotion) {
int number = 0.0;
for (int index = 0; index < [text length]; index++)
{
NSString *character = [text substringWithRange:NSMakeRange(index, 1)];
if ([character lengthOfBytesUsingEncoding:NSUTF8StringEncoding] == 3) {
number+=2;
} else {
number++;
}
if (kMaxLength == number) {
return [text substringWithRange:NSMakeRange(0, index + 1)];
}
}
}
return text;
}
解决的问题是在中文输入法下输入文字时,如果输入的字母超过长度,而实际汉字并未超过长度的问题。之前会直接截取字母,这样体验不好,高亮状态输入可以随便输入,当选择文字时再进行截取。
最后说一下UITextField和UISearchBar不同的地方,其实就是代理方法不一样,方法- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string 的作用同方法一;而UITextField中没有与方法二作用相同的方法,但是它由一个通知UITextFieldTextDidChangeNotification,这个通知的作用同方法二,因此只要注册这个通知,实现方法二中的代码即可。还有一点需要这一的是,使用完通知之后要记得移除通知。(PS:lengthOfBytesUsingEncoding:要想学习一些编码知识可以参看我的另一篇文章http://www.cnblogs.com/wfwenchao/p/4795268.html)
至此限制输入字符的全部工作就完成了。
iOS 限制UITextField输入字符的更多相关文章
- uitextfield输入字符限制
-(UITextField*)createField:(NSString*)placeholder andTag:(int)tag andFont:(double)font{ UITextField ...
- iOS中UITextField输入判断小数点后两位
在输入金额的UITextField中,要给予三个规则的判断 1. 只能输入数字(可以通过设置键盘类型为Decimal Pad) 2. 小数点只能有一个 3. 小数点后最多有两位数字 (可以通过正则表达 ...
- iOS之UITextField输入错误的震动动画
//左右震动效果 - (void)shake:(UIView *)view { CGRect frame = view.frame; CAKeyframeAnimation *shakeAnimati ...
- iOS 限制TextField输入长度(标准)
iOS 限制TextField输入长度(标准) 网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入 ...
- 限制UITextField输入内容的长度
一.前言 今天做手机号输入限制长度,例如我的textfield只能输入11位,如果再多输入的话就不再textfield中显示,只显示11位的手机号. 如果用ReactiveCocoa的话,这个很好解决 ...
- 限制 UITextField 输入长度
限制 UITextField 输入长度 标签(空格分隔): UITextField UITextField 是 iOS 中最经常使用的组件之中的一个.关于它也有各种各样的需求,这些需求是它本身没有提供 ...
- iOS textfield 限制输入字数长度
iOS textfield限制输入的最大长度 [self.textFiled addTarget:self action:@selector(textFieldDidChange:) forContr ...
- UITextView 和 UITextField限制字符数和表情符号
UITextField限制字符数 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)r ...
- EditText限制输入字符类型的几种方式
最近的项目上需要限制EditText输入字符的类型,就把可以实现这个功能的方法整理了一下: 1.第一种方式是通过EditText的inputType来实现,可以通过xml或者Java文件来设置.假如我 ...
随机推荐
- hadoop HA 之 QJM
前言 本文主要通过对hadoop2.2.0集群配置的过程加以梳理,所有的步骤都是通过自己实际测试.文档的结构也是根据自己的实际情况而定,同时也会加入自己在实际过程遇到的问题.搭建环境过程不重要,重要点 ...
- cnblog评价以及团队软件的部分改善
博客评价: 1.在word2003版本里的东西复制,不能直接直接粘贴到博客发表(发生过,大部分时候可以): 2.第一次使用的时候不知道复制过来的代码都是左对齐的,(代码排版和插入图片位置不明显): 3 ...
- Scrum仪式之Sprint计划会议
会议时间:4.15.晚八点 会议地点:基础教学楼二楼 会议进程 • 首先我们讨论了实验第一个Sprint1要实现的功能,我们的初期目标.• 然后我们进一步梳理了第一阶段的任务和需求.• 之后对任务 ...
- C#使用Socket登陆WordPress源码
就在昨晚,在本屌丝刚刚发布屌丝与女神的回忆史<C#外挂QQ找茬辅助源码,早期开发>后,在苏飞大哥的技术讨论群有个群友提出一个问题.使用http协议模拟工具可以登录成功Wordpress但是 ...
- appium-UI automator viewer 无[ resource-id ]项
问题:UI automator viewer 无[ resource-id ]项,如下图 解决办法: 手机android 版本太低导致(本人4.2.2),在android4.3机子上运行正常
- 使用IntersectionObserver更高效的监视某个页面元素是否进入了可见窗口
比如说,你想跟踪 DOM 树里的一个元素,当它进入可见窗口时得到通知. 也许想实现即时延迟加载图片功能,或者你需要知道用户是否真的在看一个广告 banner. 你可以通过绑定 scroll 事件或者用 ...
- Ubuntu 字体修改以及字体的相关知识 分类: ubuntu 2014-06-19 21:46 81人阅读 评论(0) 收藏
Ubuntu chrome 字体修改 打开任意一张含有输入框的网页,比如Google首页,然后右键点击"搜索框"会拉出一个菜单,我们这样选: 拼音检查选项==>语言设置==& ...
- 引擎设计跟踪(九.14.2e) DelayLoaded DLLs (/DELAYLOAD)
关于DLL的delay load: http://msdn.microsoft.com/en-us/library/151kt790.aspx 最近在做GLES的shader compiler, 把现 ...
- HDU1048The Hardest Problem Ever
The Hardest Problem Ever Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & ...
- JavaScript之arguments对象讲解
javascript的arguments对象类似于PHP的extract()函数实现. 在不确定函数参数个数的情况下,可以通过arguments访问参数,并以索引0为起始. function sayH ...