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> ...
随机推荐
- [iOS基础控件 - 6.7] 微博展示 使用代码自定义TableCell(动态尺寸)
A.需求 1.类似于微博内容的展示 2.头像 3.名字 4.会员标志 5.内容 6.分割线 7.配图(可选,可有可无) code source: https://github.com/hellov ...
- [Xcode使用 - 2] 设置APP图标和启动画面
1.App Icon 把所有图标文件拖放到 “Images.xcassets” 的”AppIcon” 里面 应对非视网膜和视网膜屏,APP有时会提供两套不同大小的图片,1倍图和2倍图,它们 ...
- 【Stage3D学习笔记续】真正的3D世界(六):空间大战
这就是书上的最终效果了,一个完整的空间大战游戏: 点击查看源码 这里并没有太多的新知识,所涉及的东西更多的是游戏开发方面的优化和技巧,下面我们大家一起来看看: 飞船: 类似粒子效果中的粒子创建方法,我 ...
- 【Stage3D学习笔记续】真正的3D世界(一):透视矩阵
如果各位看官跟着我的学习笔记一路看过来的话,一定会吐槽我的,这都是什么3D啊?从头到尾整个都是在使用GPU绘制一堆2D图像而已,的确,之前我们一直使用正交矩阵利用GPU加速来实现2D世界的展示,算不上 ...
- SD卡fat文件系统移植
经过充分的研究,发现fatfs文件系统移植的比较简单!因为代码都已经被别人做好了!我们只需把io层稍稍做个处理就ok了: 至于sd卡的驱动请看我这篇博客:http://blog.csdn.net/ie ...
- Java条件语句 switch case
不得不说的几点小秘密: 1. switch 后面小括号中表达式的值必须是整型或字符型 2. case 后面的值可以是常量数值,如 1.2:也可以是一个常量表达式,如 2+2 :但不能是变量或带有变量的 ...
- 已知有一个Worker 类如下: public class Worker { private int age; private String name; private double salary; public Worker (){} public Worker (String nam
package homework006; public class Worker { private int age; private String name; private double sala ...
- ThinkPHP CURD方法盘点:table方法
table方法也属于模型类的连贯操作方法之一,主要用于指定操作的数据表. 用法 一般情况下,操作模型的时候系统能够自动识别当前对应的数据表,所以,使用table方法的情况通常是为了:切换操作的数据表: ...
- jQuery遍历json
使用 each var anObject = {one:1,two:2,three:3}; $.each(anObject,function(name,value) { alert(name); al ...
- HDU 5112 A Curious Matt 水题
A Curious Matt Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid ...