iOS开发

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

2019-10-10  本文已影响0人  喔牛慢慢爬

需求:

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

问题:

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

代码:

 #define WordsNumber 50
 [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;
}
上一篇下一篇

猜你喜欢

热点阅读