美文网首页
ios中UItextfield控件(或UItextview)监测

ios中UItextfield控件(或UItextview)监测

作者: macroC | 来源:发表于2017-11-07 16:53 被阅读0次

    在 iOS 开发中,常见场景有 获取用户输入同时显示当前输入的字数。并限制输入内容的总长度,字数在临界时 裁剪用户输入。

    简单以 textfield 对象中 text 属性的 length 属性(即 textField.text.length)作为长度时,会有以下明显缺点:

    a、当前输入为中文输入,即[[UITextInputMode currentInputMode] primaryLanguage]字符串为@"zh-Hans"时,且输入法为系统自带的九宫格或全键盘时;当点击数个拼音按键,但并未选定候选词时,当前的显示的字数里就包含了候选的高亮显示的拼音字符数,造成字数显示不准。

    b、当前为中文输入,且为系统输入法时。若此时的需求中,包括用户输入的字数的限制时;普通的做法是 实时判断textField.text.length,在长度超过某个值时,对输入字符串进行裁剪,即:textField.text = [ textField.text substringToIndex : XXX] ; 此时如果当前有高亮的拼音存在,执行字符串裁剪后会出现程序崩溃( 隐约记得某几个ios系统不会出现崩溃 )。崩溃原因是 当前高亮显示的拼音部分并不是可以改动的textField.text的值,尝试改动这部分数据就会造成崩溃。想想,高亮的拼音即不可以改,又增加了长度数,想不想呵呵。。

    下面讲下目前测试的,较正确的方式:

    1、首先监听object参数对应的textfield控件的键盘动作:

    
    [[NSNotificationCenter defaultCenter]addObserver:self 
    selector:@selector(textFieldEditChanged:)
    name:@"UITextFieldTextDidChangeNotification" 
    object:self.textFieldText];
    
    

    2、定义好 textFieldEditChanged: 回调函数的动作:

    
    - (void)textFieldEditChanged:(NSNotification *)info{
    
    UITextField *textField = (UITextField *)info.object;
    
    UITextRange *range = textField.markedTextRange;    //取出marked高亮区
    
    if(range)    //表示有高亮
    
    {
    
       UITextPosition *end = range.end; 
       UITextPosition *pos = range.start; 
       NSInteger markedLength = 0;  //记录高亮区间长度
       while (markedLength < 1000) {  
          /*这里的1000表示正常输入不能达到的数,若出现极端情况,输入超过1000则只是字数
          显示不准而已,不会出现其他危险*/
    
          //后移偏移值pos  直至为end 
          pos = [self.textFieldText positionFromPosition:pos offset:1];
          if([pos isEqual:end]) 
                   break;
    
          //记录marked区长度
          ++markedLength;
       }
    NSInteger markLen = markedLength +1; //表示高亮区域长度
    self.markedLength.text = [NSString stringWithFormat:@"%ld",len]; //显示高亮区长度
    NSInteger unmarkedLen = textField.text.length - markLen; 
    //控件字符串长度,减高亮区长度,为用户已经完成输入的字符串长度。
    self.textLength.text = [NSString stringWithFormat:@"%ld",unmarkedLen ];
    }
    else //表示当前没有高亮
    {
       self.markedLength.text = @"0"; 
       self.textLength.text = [NSString stringWithFormat:@"%ld",textField.text.length];
    }
    }
    
    

    补充:获取高亮区的字符串长度并没有必要,只要在有高亮时不更新字符数,也是正常的逻辑。


    超出限定长度,并对字符串进行裁剪 的代码,自己好好考虑并添加吧。

    补充: 看了 小失同学 的这篇文章之后,发觉 在当前输入法为表情时,且由于表情占2个字符而不是普通文字的1个字符宽度,因此会造成裁剪表情,造成系统无法解析当前字符串而崩溃。

    ps:除了小失同学讲的这种情况,亲测 在第三方输入法时输入emoji表情时,当前语言输入依旧可能是@"zh-Hans",即汉字输入模式。 考虑到无论自带键盘输入,还是三方表情输入时,都是不存在前文所讲的高亮字符串。则可将这两种情况分别加 在无高亮的语句块中。

    如下代码else块表示不存在marked高亮时。


    image

    相关文章

      网友评论

          本文标题:ios中UItextfield控件(或UItextview)监测

          本文链接:https://www.haomeiwen.com/subject/eopjmxtx.html