背景
在用戶信息填寫等很多場景中腮介,UITextField輸入均有中英文字數(shù)限制望几,常見的比如中文100字、英文200字萤厅。
方案
方案1
常見的方案如下:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
if (textField == self.titleField) {
if (string.length == 0) return YES;
NSInteger existedLength = textField.text.length;
NSInteger selectedLength = range.length;
NSInteger replaceLength = string.length;
if (existedLength - selectedLength + replaceLength > 20){
return NO;
}
}
}
該方法在每輸入一個字符時都會調用橄抹,在輸入拼音聯(lián)想時,高亮的拼音長度也計算在內惕味,整個字符長度不能超過限制楼誓。比如下圖中,限制為8個中文(16個英文字符)名挥,已輸入的中文“測試測試測試”占用12個字符疟羹,待輸入的“ce s”占用4個字符,至此用戶輸入的長度已達到輸入限制禀倔,導致用戶之后想輸入的拼音都會被截斷榄融,最后的一個字很有可能就打不出來了
方案1 示例圖
方案2
為了避免方案1存在的問題,我們需要在輸入框中存在高亮待輸入文字時救湖,不做字長限制判斷愧杯,輸入確認后,再做判斷鞋既。
1.首先添加監(jiān)聽方法
#pragma mark - 直接添加監(jiān)聽方法
-(void)addTargetMethod{
[self.textField1 addTarget:self action:@selector(textField1TextChange:) forControlEvents:UIControlEventEditingChanged];
}
-(void)textField1TextChange:(UITextField *)textField{
NSLog(@"textField1 - 輸入框內容改變,當前內容為: %@",textField.text);
}
2.實現(xiàn)輸入限制方法力九,如果高亮聯(lián)想文字超過限制長度,則截斷高亮文字邑闺,盡可能保留最長的文字跌前,舍棄多余文字。
方案2 聯(lián)想輸入(字符限制16)
方案2 實際輸入(字符限制16)
-(void)textField1TextChange:(UITextField *)textField{
NSLog(@"textField1 - 輸入框內容改變,當前內容為: %@",textField.text);
NSString *toBeString = textField.text;
UITextRange *selectedRange = [textField markedTextRange];
//獲取高亮部分
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
// 沒有高亮選擇的字陡舅,則對已輸入的文字進行字數(shù)統(tǒng)計和限制
if (!position) {
textField.text = [toBeString limitedStringForMaxBytesLength:16];
}
}
這里需要注意的是抵乓, 表情符號是個坑。在本文的需求設定中,表情符號占用兩個字符長度灾炭,相當于一個中文文字章鲤。
//ascii算一個 中文算2個 emoji算2個(不標準的做法,根據(jù)substringRange可以計算出準確的字節(jié)長度)
- (NSString *)limitedStringForMaxBytesLength:(NSUInteger)maxLength {
__block NSUInteger asciiLength = 0;
__block NSUInteger subStringRangeLen = 0;
[self enumerateSubstringsInRange:NSMakeRange(0, self.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
unichar uc = [substring characterAtIndex:0];
//英文和漢字length都是1
if (substringRange.length == 1) {
//這里還有個坑咆贬, 有些空格是(uc == 0x2006)败徊,不會被 isblank和 isspace命中
//如果不允許出現(xiàn)空格,建議先取出string中的空格
if (isblank(uc) || isspace(uc) || (uc == 0x2006)) {
asciiLength += 1;
} else if (isascii(uc)) {
asciiLength += 1;
} else {
//漢字這里
asciiLength += 2;
}
} else {
//表情符號這里
asciiLength += 2;
}
if (asciiLength <= maxLength) {
subStringRangeLen = substringRange.location + substringRange.length;
}
}];
return [self substringWithRange:NSMakeRange(0, subStringRangeLen)];
}