UITextView字数限制坑一天o(╯□╰)o

96
wufeifan890330
2016.07.06 16:47* 字数 1154

近期做个小小需求的时候碰到个小问题

起初以为字数限制而已,一丢丢的小功能,用textView:shouldChangeTextInRange:shouldChangeTextInRange:方法在输入前判断是否可变更值即可。

结果慢慢的一个又一个的坑就出现了。

坑一:

iOS9以下,中文输入的情况下,点击联想字输入是不会回调textView:shouldChangeTextInRange:shouldChangeTextInRange:这个方法的。

于是,联想词各种狂点。 一小会输入框满满全是~~~~

好吧。只能在textViewDidChange:方法内判断了。

于是,唰唰唰在textViewDidChange:中加入三行代码。

if(textView.text.length>NM_CARREPORT_TEXTLENGTH_MAX){

textView.text=[textView.text substringToIndex:NM_CARREPORT_TEXTLENGTH_MAX];

}

果断run起来,开始噼里啪啦的狂敲屏幕自测【其实是抽空休息来着】。

“Bon…” crash了!!!

纳尼?! what are you 弄啥嘞?!!!我玩个textView,你要是crash在string相关的也就算了。 你特喵崩在array这种玩意上是闹哪样!!!

惆怅了半天,,好吧,,继续填坑。。。

坑二

crash是在textView截断的时候出现,唔,setMarkedText:selectedRange:是设置文字,然后内部进行富文本的替换。

苦思冥想半天,真真是不得其解,为啥崩了。

直到,突然发现在中文输入下,连续输入声母中间会出现空格, 哇咔咔~~ 悟了 O(∩_∩)O哈哈哈~

赶紧验证一下自己的想法,果然。。。

崩溃的原因在于,假设要设置的上限是100个字符,当输入98个字符以后,连续输入两个声母,此时系统自动在中间添加一个空格,进入到textViewDidChanged:中,textView.text的长度变成101,进入到截断字符串的逻辑中,截掉最后一个字符,那么剩余100个字符的最后一个是系统自动增加的空格。将整个串重新赋给textView.text的时候,系统无法识别空格(特喵的自己生的都不认。日了狗了了~~),于是就华丽丽的崩了。【经检验,若最后两个字符输入的是形如ch酱紫的,不会产生空格的连续字符,就不会有问题】。

不过也对,原本textView:shouldChangeTextInRange:shouldChangeTextInRange:就是用来过滤输入文本的,既然进入到textViewDidChange:中了,自然文本就是需要的,岂能容你随意更改!【so。 机智的苹果偷偷摸摸的在iOS9上更改了联想文字输入的逻辑。也走textView:shouldChangeTextInRange:shouldChangeTextInRange:方法了】

问题找到了,接下来就是填坑了。

机智如我,小小问题岂能难倒,

if(textView.text.length>NM_CARREPORT_TEXTLENGTH_MAX+1){

textView.text=[textView.text substringToIndex:NM_CARREPORT_TEXTLENGTH_MAX+1];

}

哈哈。宝宝是不是好机智,酱紫正常输入就不会进入到该方法了!因为在textView:shouldChangeTextInRange:shouldChangeTextInRange:中已经限制了。 而联想输入,就让你多输入一个字嘛~ 反正一般人看不出来。

坑三

天真的我低估了我厂QA同学的敬业程度,居然生生测出这BUG。 101个字和100个字~~~!!! 我说同学,你要不要这么屌。。。。 一个个去数你也是棒棒哒!!!

既然QA同学提出意见了。作为一名敬业的RD。必须fix掉啊!

然而。。。 天知道怎么搞。。。 机(bai)智(wu)如(liao)我(lai),继续翻API找去。

咦?!markedTextRange 这个是什么鬼?!

/* If text can be selected, it can be marked. Marked text represents provisionally

* inserted text that has yet to be confirmed by the user.It requires unique visual

* treatment in its display.If there is any marked text, the selection, whether a

* caret or an extended range, always resides witihin.

*

* Setting marked text either replaces the existing marked text or, if none is present,

* inserts it from the current selection. */

好吧。直译就是标记文本,代表临时的插入待用户确认的文本,简单来说,这个其实就是中文输入时,高亮的英文部分。。中文输入下并且有高亮的英文部分时,这玩意儿就有值了。

到这里,这坑就填一半了。

if(textView.text.length > NM_CARREPORT_TEXTLENGTH_MAX && textView.markedTextRange == nil){

textView.text=[textView.text substringToIndex:NM_CARREPORT_TEXTLENGTH_MAX];

}

呼,搞定~~

iOS
Web note ad 1