在项目开发过程中,遇到这么一个需求,编辑标签时,输入的最大长度需要限制为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进行字符长度限制的办法的更多相关文章

  1. url字符长度限制解决办法

    前段时间,同事往系统上传相关文档,发现输入失败,找到了我了. 开始以为数据库字段属性问题,修改后未解决随调试系统,发现没有走到后台程序,发现 ajax没有传值,各种测试问题情况,后来同事发现是url字 ...

  2. iOS 学习 - 7.限制 TextField 输入字符长度

    #pragma mark -- TextField代理 -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange: ...

  3. iOS 限制textField输入的长度

    1.电话号码(带3-3-4效果) //指定代理 self.phoneTextField.delegate = self; //当编辑改变的时候,进行字符校验 [self.phoneTextField ...

  4. iOS 限制TextField输入长度(标准)

    iOS 限制TextField输入长度(标准) 网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入 ...

  5. iOS之限制TextField的输入长度

    网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入长度的方法.我所采用的并不是监听方法而是最不同的 ...

  6. iOS:UITextField中文输入法输入时对字符长度的限制

      如题的问题,又是个让我抓狂了大半天的问题,还是做个记录,有与类似问题的同学可参考,但不一定对.具体问题还需具体分析.我遇到的需求是这样的:有一个输入框,输入框内输入文字,文字字数限制在20字.   ...

  7. iOS(Swift) TextField限制输入文本的长度(不是字数)

    最近做项目有一个特殊需求,就是需要限制一个TextField的输入文本的长度在一定范围内(注意,不是字数),上网查了一圈没有找到类似文章,这里把我的方法写进来,mark一下: 1.对TextField ...

  8. 动态SQL字符长度超过8000

    动态SQL字符长度超过8000,我记得SQL SERVER 2008中用SP_EXECUTESQL打破了这个限制. 平常用动态SQL,可能都会用EXEC(),但是有限制,就是8000字符串长度.自从S ...

  9. 解决MVC中JSON字符长度超出限制的异常

    解决MVC中JSON字符长度超出限制的异常 解决方法如下: <configuration> <system.web.extensions> <scripting> ...

随机推荐

  1. [iOS基础控件 - 4.3] APP列表 xib的使用

    A.storyboard和xib 1.storyboard: 相对xib较重量级,控制整个应用的所有界面 2.xib: 轻量级,一般用来描述局部界面   B.使用 1.新建xib文件 New File ...

  2. [OC Foundation框架 - 1] 常用结构体

    底层封装是使用了typedef定义的结构体 typedef struct _NSString{ xxx xxx } NSString;   1. NSRange 结构体 #注意结构体不是对象 3种定义 ...

  3. C++学习笔记(六):复杂数据类型(string、容器和STL)

    STL 即Standard Template Library(标准模板库),由于C++自带的数据类型过于简单,并不能满足我们的使用需要,而STL作为C++标准的内置库为我们编写好了多种高效的数据结构和 ...

  4. USACO Feb. 2012

    Moo 找规律 吧 第一个是很久以前自己写的递归 #include<stdio.h> __int64 n; __int64 dfs(__int64 l,__int64 r,__int64 ...

  5. 制作第三方SDK静态库、.framework

    静态库和动态库的存在形式 静态库: .a 和 .framework 动态库: .dylib 和 .framework 静态库和动态库的使用区别: 静态库:链接时,静态库会被完整地复制 到 可执行文件中 ...

  6. 使用hexdump 查看二进制文件

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...

  7. [Practical Git] Show who changed a line last with git blame

    When working on a file, we often want to know who made certain changes last; we can use git blame to ...

  8. RapidXml用法

    一.写xml 文件 #include <iostream> #include "rapidxml/rapidxml.hpp" #include "rapidx ...

  9. SAP-SD-ABAP-VMOD 查找和应用SD模块用户出口(user exit) 好方法 .

    针对 SD 模块,有一个专门管理 user-exit 的开发包  VMOD , 只要用tcode: se80 查看它, 会发现绝大部分的 SD 要相关的 user-exit 都能在这找到.

  10. Maven项目中如何添加日志