zoukankan      html  css  js  c++  java
  • UITextField限制汉字数量最正确的姿势,解决iOS7下substringToIndex方法导致的崩溃

    今天在写一个限制UITextField汉字数量的需求,原以为非常简单的一个需求,在实际开发中遇到了很多问题.

    首先,汉字的输入时的联想词在输入到TextFiled时,并不会走

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;

    这导致了在这里进行长度限制的代码都会失效.此路不通.

    经过查找资料,得知可以用注册UITextFieldTextDidChangeNotification通知来监测TextField的文字的变化

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(textFiledEditChanged:) 
              name:@"UITextFieldTextDidChangeNotification" object:myTextField];
    

      

    在textFiledEditChanged:方法中

    - (void)textDidChanged:(NSNotification *)notification{
        
        NSInteger maxLength = 6;
        UITextField *textField = (UITextField *)notification.object;
    
        if (textField.text.length > maxLength)
        {
            textField.text = [textField.text substringToIndex:maxLength];
        }
    }
    

      这种方法看起来没什么问题,然而实测在iOS7下输入汉字时,一旦长度到达最大长度,再进行输入(此时输入状态还是拼音)就会立即崩溃.

    *** Terminating app due to uncaught exception 'NSRangeException', reason: 'NSMutableRLEArray replaceObjectsInRange:withObject:length:: Out of bounds'

    该问题在iOS8以上的系统中不会出现,可能是苹果修复了该BUG.

    再次查找资料,找到这篇博客http://www.jianshu.com/p/2d1c06f2dfa4

    这篇博客解决了UItextFiled在截取字符串时,如果对emoji进行截取会变乱码的问题(原因是emoji实际上占了3个长度).

    UITextField *textField = (UITextField *)obj.object;
        NSString *toBeString = textField.text;
    
        //获取高亮部分
        UITextRange *selectedRange = [textField markedTextRange];
        UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
    
        // 没有高亮选择的字,则对已输入的文字进行字数统计和限制
        if (!position)
        {
            if (toBeString.length > MAX_STARWORDS_LENGTH)
            {
                NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:MAX_STARWORDS_LENGTH];
                if (rangeIndex.length == 1)
                {
                    textField.text = [toBeString substringToIndex:MAX_STARWORDS_LENGTH];
                }
                else
                {
                    NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, MAX_STARWORDS_LENGTH)];
                    textField.text = [toBeString substringWithRange:rangeRange];
                }
            }
        }

    测试后发现,这个方法在iOS8以上的系统运行良好,但是在iOS7下居然完全失效了.

    原因是在iOS7下,position对象总是不为nil,导致走不进处理长度的代码.

    研究后发现在需要增加一个判断条件,

    改进后的代码:

    UITextField *textField = (UITextField *)obj.object;
        NSString *toBeString = textField.text;
    
        //获取高亮部分
        UITextRange *selectedRange = [textField markedTextRange];
        UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
    
        // 没有高亮选择的字,则对已输入的文字进行字数统计和限制
        if (!position || !selectedRange)
        {
            if (toBeString.length > MAX_STARWORDS_LENGTH)
            {
                NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:MAX_STARWORDS_LENGTH];
                if (rangeIndex.length == 1)
                {
                    textField.text = [toBeString substringToIndex:MAX_STARWORDS_LENGTH];
                }
                else
                {
                    NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, MAX_STARWORDS_LENGTH)];
                    textField.text = [toBeString substringWithRange:rangeRange];
                }
            }
        }
    

    再次测试后没有发现崩溃问题了.

  • 相关阅读:
    无线鼠标换电池了
    Jython Interactive Servlet Console YOU WILL NEVER KNOW IT EXECLLENT!!! GOOD
    Accessing Jython from Java Without Using jythonc
    jython podcast cool isnt't it?
    Python里pycurl使用记录
    Creating an Interactive JRuby Console for the Eclipse Environment
    微软为AJAX和jQuery类库提供CDN服务
    Download A File Using Cygwin and cURL
    What is JMRI?这个是做什么用的,我真没看懂但看着又很强大
    用curl 发送指定的大cookie的http/https request
  • 原文地址:https://www.cnblogs.com/ashamp/p/5199152.html
Copyright © 2011-2022 走看看