美文网首页iOS开发
iOS在UITextField 输入string限制长度,解决输

iOS在UITextField 输入string限制长度,解决输

作者: 喔牛慢慢爬 | 来源:发表于2019-10-10 10:22 被阅读0次

    需求:

    在文本输入框中输入文字时限制输入字符数为50,可以输入emoji头像。

    问题:

    1. 输入汉字时拼音也会被算入计数,被限制;
    2. 输入emoji头像时在最后截取时出现头像被截取一半的情况;

    代码:

     #define WordsNumber 50
    
    • 添加注册UITextField事件监听:
     [self.textField addTarget:self action:@selector(textFieldEditChanged:) forControlEvents:UIControlEventEditingChanged];
    
    • 监听方法实现
    - (void)textFieldEditChanged:(UITextField *)textField
    {
        NSString *lang = [textField textInputMode].primaryLanguage;
        if (StringEqual(lang, @"zh-Hans")) {
            //输入简体中文内容
            //获取高亮部分,如拼音
            UITextRange *selectedRange = [textField markedTextRange];
            UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
            if (!position) {
                [self handleTextFieldCharLength:textField];
            }
        }
        else{
            //输入简体中文以外的内容
            [self handleTextFieldCharLength:textField];
        }
    }
    
    • 输入字符超出限制处理
    - (void)handleTextFieldCharLength:(UITextField *)textField
    {
        NSString *toBeString = textField.text;
        if (textField.text.length > WordsNumber) {
            //获取超过50最大字符数的多余字符range
            NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:WordsNumber];
            if (rangeIndex.length == 1){
                //如果多余字符的length = 1,则直接截取最大字符数
                textField.text = [toBeString substringToIndex:WordsNumber];
            }
            else{
                //如果多余字符的length > 1,则截取位置为(0.50),按输入内容单位截取
                NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, WordsNumber)];
                textField.text = [toBeString substringWithRange:rangeRange];
            }
        }
    }
    

    解决输入emoj被截取一半的问题:

    在官方文档中已经提供了解决方法:

    /* To avoid breaking up character sequences such as Emoji, you can do:
        [str substringFromIndex:[str rangeOfComposedCharacterSequenceAtIndex:index].location]
        [str substringToIndex:NSMaxRange([str rangeOfComposedCharacterSequenceAtIndex:index])]
        [str substringWithRange:[str rangeOfComposedCharacterSequencesForRange:range]
    */
    - (NSString *)substringFromIndex:(NSUInteger)from;
    - (NSString *)substringToIndex:(NSUInteger)to;
    - (NSString *)substringWithRange:(NSRange)range;
    
    - (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)index;
    - (NSRange)rangeOfComposedCharacterSequencesForRange:(NSRange)range 
    

    最后记录下判断文本中是否存在emoji的方法:

    //过滤所有表情
    + (BOOL)stringContainsEmoji:(NSString *)string {
        __block BOOL returnValue = NO;
        [string enumerateSubstringsInRange:NSMakeRange(0, [string length]) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
            const unichar hs = [substring characterAtIndex:0];
            // surrogate pair
            if (0xd800 <= hs && hs <= 0xdbff) {
                if (substring.length > 1) {
                    const unichar ls = [substring characterAtIndex:1];
                    const int uc = ((hs - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
                    if (0x1d000 <= uc && uc <= 0x1f9c0) {
                        returnValue = YES;
                    }
                }
            } else if (substring.length > 1) {
                const unichar ls = [substring characterAtIndex:1];
                if (ls == 0x20e3||ls == 0xfe0f ||ls == 0xd83c) {
                    returnValue = YES;
                }
            } else {
                // non surrogate
                if (0x2100 <= hs && hs <= 0x27ff) {
                    returnValue = YES;
                }
                else if (0x2B05 <= hs && hs <= 0x2b07)
                {
                    returnValue = YES;
                }
                else if (0x2934 <= hs && hs <= 0x2935) {
                    returnValue = YES;
                }
                else if (0x3297 <= hs && hs <= 0x3299) {
                    returnValue = YES;
                }
                else if (hs == 0xa9 || hs == 0xae || hs == 0x303d || hs == 0x3030 || hs == 0x2b55 || hs == 0x2b1c || hs == 0x2b1b || hs == 0x2b50) {
                    returnValue = YES;
                }
            }
        }];
        return returnValue;
    }
    

    相关文章

      网友评论

        本文标题:iOS在UITextField 输入string限制长度,解决输

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