需求:
在文本輸入框中輸入文字時限制輸入字符數(shù)為50压储,可以輸入emoji頭像鲜漩。
問題:
- 輸入漢字時拼音也會被算入計(jì)數(shù),被限制集惋;
- 輸入emoji頭像時在最后截取時出現(xiàn)頭像被截取一半的情況孕似;
代碼:
#define WordsNumber 50
- 添加注冊UITextField事件監(jiān)聽:
[self.textField addTarget:self action:@selector(textFieldEditChanged:) forControlEvents:UIControlEventEditingChanged];
- 監(jiān)聽方法實(shí)現(xiàn)
- (void)textFieldEditChanged:(UITextField *)textField
{
NSString *lang = [textField textInputMode].primaryLanguage;
if (StringEqual(lang, @"zh-Hans")) {
//輸入簡體中文內(nèi)容
//獲取高亮部分,如拼音
UITextRange *selectedRange = [textField markedTextRange];
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
if (!position) {
[self handleTextFieldCharLength:textField];
}
}
else{
//輸入簡體中文以外的內(nèi)容
[self handleTextFieldCharLength:textField];
}
}
- 輸入字符超出限制處理
- (void)handleTextFieldCharLength:(UITextField *)textField
{
NSString *toBeString = textField.text;
if (textField.text.length > WordsNumber) {
//獲取超過50最大字符數(shù)的多余字符range
NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:WordsNumber];
if (rangeIndex.length == 1){
//如果多余字符的length = 1刮刑,則直接截取最大字符數(shù)
textField.text = [toBeString substringToIndex:WordsNumber];
}
else{
//如果多余字符的length > 1喉祭,則截取位置為(0.50),按輸入內(nèi)容單位截取
NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, WordsNumber)];
textField.text = [toBeString substringWithRange:rangeRange];
}
}
}
解決輸入emoj被截取一半的問題:
在官方文檔中已經(jīng)提供了解決方法:
/* 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;
}