iOS UITextField限制字符长度

作者: BigWangHaHa | 来源:发表于2016-10-08 16:33 被阅读1135次

    声明:

    1.文章内容参考了网上部分博客,如涉及到版权问题,请及时联系我,我会第一时间处理。
    2.文章内容是个人观点,如有错误的地方也请及时联系我,谢谢。

    1.关于限制字符长度的坑

    拿到需求的时候我首先想到的是使用UITextFieldDelegate 的方法- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;

    像这样:

    -(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string {
          // text field 上实际字符长度
          NSIntegerstrLength = textField.text.length - range.length + string.length; 
          return(strLength <= 5);
    }
    

    但是,这种方法经过实际测试,只适用于英文和符号输入,当涉及到中文输入时,这里涉及到一个概念:我叫它“高亮选中内容”。如下图:


    高亮选中内容.png

    上面代码中我们限制字符长度是5,但是其实当我想输入第四个汉字“瓜”时,“西门西gu”这个字符穿的长度已经是5了,然后你的代理方法就会返回NO给你,这时我们就已经不能再输入其他字符了。

    经过上面的坑之后,我在网上浏览的很多博客,找到了下面正确的方法(使用UITextFieldTextDidChangeNotification通知):

    限制字符长度的正确方法:

    1.添加通知
     // 添加监听
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewEditChanged:) name:UITextFieldTextDidChangeNotification object:nil];
    

    注意:添加监听后记得移除。

    2.实现监听方法
    
    /**
     *  当 text field 文本内容改变时 会调用此方法
     *
     *  @param notification
     */
    -(void)textViewEditChanged:(NSNotification *)notification{
        
        // 拿到文本改变的 text field
        UITextField *textField = (UITextField *)notification.object;
        // 需要限制的长度
        NSUInteger maxLength = 0;
        if (textField.tag == 101) { // 中文名字限制长度
            maxLength = 5;
        }
        if (textField.tag == 102) { // 英文名限制长度
            maxLength = 10;
        }
        if (maxLength == 0) return;
        
        // text field 的内容
        NSString *contentText = textField.text;
        
        // 获取高亮内容的范围
        UITextRange *selectedRange = [textField markedTextRange];
        // 这行代码 可以认为是 获取高亮内容的长度
        NSInteger markedTextLength = [textField offsetFromPosition:selectedRange.start toPosition:selectedRange.end];
        // 没有高亮内容时,对已输入的文字进行操作
        if (markedTextLength == 0) {
            // 如果 text field 的内容长度大于我们限制的内容长度
            if (contentText.length > maxLength) {
                // 截取从前面开始maxLength长度的字符串
    //            textField.text = [contentText substringToIndex:maxLength];
                // 此方法用于在字符串的一个range范围内,返回此range范围内完整的字符串的range
                NSRange rangeRange = [contentText rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, maxLength)];
                textField.text = [contentText substringWithRange:rangeRange];
            }
        }
    
    }
    

    上面这段代码中,一开始在截取字符串时我使用的是substringToIndex,但是我们可能会遇到emoji表情无法正确显示的问题,如下图:

    emoji表情无法正常显示.png

    当我们用substringToIndex这个方法时,在我们输入的第5个字符是emoji表情时,就可能会像上图显示的那样。
    在苹果认为汉字和英文字母的长度是1,而emoji表情的长度是2,就类似于你可以直接在QQ输入栏里输入“/shd”当做“闪电”表情使用。所以当我们以为我们截取的是“西门西瓜/shd”,其实我们只截取了“西门西瓜/”。

    而当我们使用rangeOfComposedCharacterSequencesForRange时,就可以避免这种情况发生。
    rangeOfComposedCharacterSequencesForRange 这个方法就像我在上面注释的一样,它可以保证你range范围内字符串的完整性。所以我们先用这个方法取到完整的字符串的range,然后用substringWithRange取到我们想要的字符串。

    相关文章

      网友评论

      本文标题:iOS UITextField限制字符长度

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