iOS文本字?jǐn)?shù)限制處理

實(shí)際開(kāi)發(fā)中經(jīng)常遇到文本字?jǐn)?shù)限制的需求,比如發(fā)布朋友圈時(shí)輸入正文長(zhǎng)度不能超過(guò)1000字,輸入用戶名時(shí)限制長(zhǎng)度不能超過(guò)10個(gè)字符。有時(shí)要求中文和表情都按照一個(gè)字符計(jì)數(shù),有時(shí)要求按照兩個(gè)字符計(jì)數(shù)。甚至,有時(shí)還要限制用戶名中不能包含除數(shù)字、字母、中外外的其他字符。

不同字符的長(zhǎng)度

  • 英文字符:字符串長(zhǎng)度為1,字節(jié)長(zhǎng)度為1
  • 中文字符:字符串長(zhǎng)度為1,字節(jié)長(zhǎng)度為2
  • emoji符號(hào):字符串長(zhǎng)度可能為2、5、7、11等等,字節(jié)長(zhǎng)度可能為4、12、18等(emoji可以通過(guò)添加控制符進(jìn)行變體、通過(guò)添加鏈接符進(jìn)行連接等)
  • 其他字符:不同語(yǔ)言的字符各不相同

文本輸入控件

  • UITextField:通過(guò)監(jiān)聽(tīng)通知UITextFieldTextDidChangeNotification實(shí)現(xiàn)在控件文本內(nèi)容發(fā)生變化時(shí)進(jìn)行字?jǐn)?shù)限制判斷。再使用代理方法-textField:shouldChangeCharactersInRange:replacementString:配合實(shí)現(xiàn)輸入控制。
  • UITextView:通過(guò)代理方法-textViewDidChange:和-textView:shouldChangeTextInRange:replacementText:
    通常需要在控件文本內(nèi)容發(fā)生變化時(shí),進(jìn)行字?jǐn)?shù)限制判斷。

統(tǒng)計(jì)字符串的字符個(gè)數(shù)

NSInteger len = text.length;

統(tǒng)計(jì)字符串的字節(jié)長(zhǎng)度

  NSStringEncoding enc =   CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
  NSData *data = [text dataUsingEncoding:enc];
  NSInteger dataLen = data.length;

遍歷字符串

[text enumerateSubstringsInRange:NSMakeRange(0, text.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
    //
}];

UITextView實(shí)例

#pragma mark - UITextViewDelegate

- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
    if (text.length == 0) { return YES; }
    return textView.text.length < 30;
}

- (void)textViewDidChange:(UITextView *)textView
{
    NSString *text = textView.text;
    NSInteger c = 30;
    if (text.length > c)
    {
        if (textView.markedTextRange) { return; }
        textView.text = [text substringToIndex:c];
    }
}

UITextField實(shí)例

#pragma mark - UITextField Change Text

- (void)textFieldTextDidChange:(NSNotification *)notification
{
    UITextField *textField = notification.object;
    NSString *text = textField.text;
    NSInteger c = 8;

    NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSData *data = [text dataUsingEncoding:enc];

    if (data.length > c)
    {
        if (textField.markedTextRange) { return; }
    
        NSMutableString *newText = [NSMutableString string];
        __block NSInteger count = 0;
    
        [text enumerateSubstringsInRange:NSMakeRange(0, text.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
        
            NSData *da = [substring dataUsingEncoding:enc];
            if (da.length <= c - count)
            {
                [newText appendString:substring];
                count += da.length;
            }
            else
            {
                *stop = YES;
            }
        }];
    
        textField.text = newText;
    }
}

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSLog(@"string:%@, range:%@", string, [NSValue valueWithRange:range]);
    if (string.length == 0) { return YES; }

    NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
    NSData *data = [textField.text dataUsingEncoding:enc];
    return data.length < 8;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容