iOS对textField进行字符长度限制的办法
在项目开发过程中,遇到这么一个需求,编辑标签时,输入的最大长度需要限制为24个字节。
查阅了一些材料,并参考了之前项目的相关处理办法,今天在这里总结一下解决方案。
1.写一个截取字符串的方法,将超长的字符串截取成符合长度的字符串。如果内容超长,就干掉最后一个字,再判断是否超过限制长度,如此循环,直到满足长度限制要求。这里注意一下,直接使用length方法,返回的字符数,而不是字节数,lengthOfBytesUsingEncoding可返回指定字符编码的字节数。
这里遇到了一个特殊的问题:当字符串最后一个字符是emoji表情符号时,如果长度超限,会发现截取后的字符串最后有乱码。究其原因,一般的汉字和英文字符,都只占一个lengh单位,例如“我是Tom”的lengh就是5。但是表情符号可能占多个length单位,比如2个或者3个,甚至更多。所以,只把最后一个length单位截取掉,其实是没有把该表情符号完全删除掉的。幸运的是,我们仍然可以使用lengthOfBytesUsingEncoding来解决此问题,当一个utf8字符的编码不完整时,我们发现lengthOfBytesUsingEncoding返回0,把这种情况也处理一下即可。
/**
* 截取字符串,使字符串满足最大长度要求
*
* @param sourceString 待截取的字符串
*
* @return 截取后的字符串
*/
-(NSString*)truncatedString:(NSString*)sourceString
{
NSString *temp = [NSString stringWithString:sourceString];
while(YES)
{
NSInteger stringLen = [temp lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; if(stringLen == && temp.length != )
{
//当字符串的length不为零,stringLen为0时,代表字符串包含了不完整的UTF8编码的字符,取自身length-1的字符串
temp = [temp substringToIndex:temp.length-];
continue;
} if (stringLen <= kMaxByteOfAlarmName) {
//字符串符合长度要求
break;
}
else
{
//字符串过长,取自身length-1的字符串
temp = [temp substringToIndex:temp.length-];
}
}
return temp;
}
2.添加对UITextField的编辑变化事件的监听:
[self.textField addTarget:self action:@selector(textLengthChange:) forControlEvents:UIControlEventEditingChanged];
3.实现对应的action:
-(void)textLengthChange:(id)sender
{
UITextField * textField=(UITextField*)sender;
if (textField.markedTextRange == nil)
{
NSString *truncatedString = [self truncatedString:textField.text];
if(![textField.text isEqualToString:truncatedString])
{
textField.text = truncatedString;
}
}
}
说明:
另外,中文输入时,和平时英文输入会不太一样,中文输入会出现正在输入拼音,还没有选汉字,拼音已经上去了:
这时,拼音本身占的字节可能大于选字后的汉字所占的字节,例如输入zhong,占5个字节,而如果用户选择“中”,只占三个字节。如果不专门考虑这种情况,就会出现明明还可以再输一个中文汉字,但是输入拼音的时候没法完成zhong的拼音输入。所以需要判断当时textField是否有已选中的内容。至于为什么要先判断是否截取前后相等,是因为如果截取了,光标会自动跑到最后去,所以当用户输入没有超长时,我们最好不要改变光标的位置。
4.针对步骤3中的图,如果在出现图中的状态下直接保存,那么textfiled会把未转换为汉字的拼音也一起保存进去。所以还需要在使用textfield的内容前再进行一下处理,把超出的部分删除,再执行一遍截取:
self.textField.text = [self truncatedString:self.textField.text];
Done。如果有什么问题,欢迎留言指出,一起讨论。
补充点东西:
为什么不用UITextField的代理方法shouldChangeCharactersInRange?
目前看来,此方法无法捕捉粘贴、拼音转汉字和联想(例如使用拼音输“中国”后,直接再键盘的候选词中可以选“万岁”)输入导致的变化。所以不采用。
更新:
2016.7.25:将相同的代码提取成方法,增加对表情等特殊字符的处理。另外,考虑一种场景,即输入时,光标不在末尾的情况,那么随着用户的输入,最后的字符将会删除。体验更好的情况应该是删除新输入的字符串的末尾。但由于我们无法获取到新输入的字符串(shouldChangeCharactersInRange 有局限性),可以考虑直接撤销本次更改,保留上次的内容(这要求每次输入完成后,需要将现有的内容保存起来)。鉴于这种场景很少见,且当前处理也不会出现超限的问题,暂时不处理。
iOS对textField进行字符长度限制的办法的更多相关文章
- url字符长度限制解决办法
前段时间,同事往系统上传相关文档,发现输入失败,找到了我了. 开始以为数据库字段属性问题,修改后未解决随调试系统,发现没有走到后台程序,发现 ajax没有传值,各种测试问题情况,后来同事发现是url字 ...
- iOS 学习 - 7.限制 TextField 输入字符长度
#pragma mark -- TextField代理 -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange: ...
- iOS 限制textField输入的长度
1.电话号码(带3-3-4效果) //指定代理 self.phoneTextField.delegate = self; //当编辑改变的时候,进行字符校验 [self.phoneTextField ...
- iOS 限制TextField输入长度(标准)
iOS 限制TextField输入长度(标准) 网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入 ...
- iOS之限制TextField的输入长度
网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入长度的方法.我所采用的并不是监听方法而是最不同的 ...
- iOS:UITextField中文输入法输入时对字符长度的限制
如题的问题,又是个让我抓狂了大半天的问题,还是做个记录,有与类似问题的同学可参考,但不一定对.具体问题还需具体分析.我遇到的需求是这样的:有一个输入框,输入框内输入文字,文字字数限制在20字. ...
- iOS(Swift) TextField限制输入文本的长度(不是字数)
最近做项目有一个特殊需求,就是需要限制一个TextField的输入文本的长度在一定范围内(注意,不是字数),上网查了一圈没有找到类似文章,这里把我的方法写进来,mark一下: 1.对TextField ...
- 动态SQL字符长度超过8000
动态SQL字符长度超过8000,我记得SQL SERVER 2008中用SP_EXECUTESQL打破了这个限制. 平常用动态SQL,可能都会用EXEC(),但是有限制,就是8000字符串长度.自从S ...
- 解决MVC中JSON字符长度超出限制的异常
解决MVC中JSON字符长度超出限制的异常 解决方法如下: <configuration> <system.web.extensions> <scripting> ...
随机推荐
- Javascript注意事项四【提高循环性能的策略】
for(var i = item.length;i--){ process(item[i]); } 1.通过倒叙循环 2.最小化属性查询 3.尽量不要使用函数迭代(forEach)
- js避免全局污染
避免声明全局变量,以免发生冲突
- hdu 5443 The Water Problem 线段树
The Water Problem Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php? ...
- BAPI_ACC_DOCUMENT_POST Enter rate / GBP rate type M for Error SG105
Folks, I was wondering if I could get a bit of help here as I've been racking my brains on it for ag ...
- percona监控模板图形解释
http://blog.itpub.net/28916011/viewspace-1971933/ percona监控mysql的几张图形解释 最近,我仔细研究了一下percona监控mysq ...
- 详解C中volatile关键字
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...
- java_类泛型基本实例
package ming; public class Apple2<T> { public T info; public Apple2(T info) { this.info = info ...
- com.service.impl
package com.service.impl; import java.util.ArrayList; import java.util.LinkedHashMap; import java.ut ...
- What Influences Method Call Performance in Java?--reference
reference from:https://www.voxxed.com/blog/2015/02/too-fast-too-megamorphic-what-influences-method-c ...
- linux 常识笔记 20160621
Linux分四部分 Linux内核 GNU工具组建 图形化桌面环境 应用软件 Linux系统的核心是内核,内核控制着计算机系统上的所有硬件和软件:必要时分配硬件,有需要时执行软件. 内核负责四项主要功 ...