首先,说一下UITextField的限制输入方法,要限制一个UITextField的输入字数,首先想到的应该是通过
UITextFieldDelegate
设置textField.delegate = self;
然后实现以下代理方法
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
if (textField.text.length > 20) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:@"最多可输入20个字"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil, nil];
[alert show];
return NO;
}
return YES;
}
这是最简单的限制方法,然而还有好多蛋疼的问题需要考虑,比如,中文占两个字符,非中文占一个字符的问题。当你想输入最后一个字的时候,你会发现拼音刚输入两个字母(字还没拼出来)就会显示长度超出。还有使用中文输入法的时候,有词汇联功能,那样这个代理方法是监控不到的。
首先解决第一个中英文占位不同的问题。这时候需要获取输入内容中中文的个数,出现一个中文就把长度加一。
接下来处理最后一个字拼写不了的问题,我们知道,在使用中文输入的时,拼写拼音的时候,输入框里面的拼音是处于高亮状态的。我们现在就利用这一特点来解决最后一个字的拼写问题,当输入框内容是高亮是先不做长度判断。
最后,联想输入情况下,此代理失效的问题。这个时候我们需要给textField添加一个事件,当textField发生编辑时调用
[textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
在这个事件中做与上面代理方法中相同的处理即可。
完整代码如下:
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range
replacementString:(NSString *)string {
NSString * toBeString = [textField.text stringByReplacingCharactersInRange:range
withString:string];//得到输入框的内容
return [self checkText:toBeString forTextField:textField];
}
- (void)textFieldDidChange:(UITextField *)textField {
//得到输入框的内容
[self checkText:textField.text forTextField:textField];
}
-(BOOL)checkText:(NSString *)toBeString forTextField:(UITextField *)textField {
NSString *lang = [textField.textInputMode primaryLanguage];//键盘输入模式
if ([lang isEqualToString:@"zh-Hans"]) {//简体中文输入模式,包括简体拼音,五笔,手写
UITextRange *selectedRange = [textField markedTextRange];
//获取高亮部分
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
if (!position) {//如果没有高亮,判断字数是否超限
NSUInteger charLen = [self lengthWithString:toBeString];
if (charLen > 20) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:@"最多可输入10个汉字"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil, nil];
[alert show];
return NO;
}
} else {//有高亮状态,暂不处理
}
} else {//不是中文输入模式
NSUInteger charLen = [self lengthWithString:toBeString];
if (charLen > 20) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:@"最多可输入20个字符"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil, nil];
[alert show];
return NO;
}
}
return YES;
}
- (NSUInteger)lengthWithString:(NSString *)string {
NSUInteger len = string.length;
NSString *pattern = @"[\u4e00-\u9fa5]";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive error:nil];
//计算中文字符个数
NSUInteger numMatch = [regex numberOfMatchesInString:string options:NSMatchingReportProgress
return len + numMatch;
}
最后来说一下textView的处理方法。这个就比较简单了,因为textView有这个代理方法- (void)textViewDidChange:(UITextView *)textView
,这样就不用考虑联想输入的问题了。代码如下
- (void)textViewDidChange:(UITextView *)textView {
NSString *lang = [textView.textInputMode primaryLanguage];//键盘输入模式
if ([lang isEqualToString:@"zh-Hans"]) {//简体中文输入模式,包括简体拼音,五笔,手写
UITextRange *selectedRange = [textView markedTextRange];
//获取高亮部分
UITextPosition *position = [textView positionFromPosition:selectedRange.start offset:0];
if (!position) {//如果没有高亮,判断字数是否超限
NSUInteger charLen = [self lengthWithString:textView.text];
if (charLen > 20) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:@"最多可输入10个汉字"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil, nil];
[alert show];
}
} else {//高亮状态,不处理
}
} else {//非中文输入模式
NSUInteger charLen = [self lengthWithString:textView.text];
if (charLen > 20) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil
message:@"最多可输入20个字符"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil, nil];
[alert show];
}
}
}
- (NSUInteger)lengthWithString:(NSString *)string {
NSUInteger len = string.length;
NSString *pattern = @"[\u4e00-\u9fa5]";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern
options:NSRegularExpressionCaseInsensitive error:nil];
//计算中文字符个数
NSUInteger numMatch = [regex numberOfMatchesInString:string options:NSMatchingReportProgress
range:NSMakeRange(0, len)];
return len + numMatch;
}
本人才疏学浅,如有不对的地方,欢迎大家提出,共同学习。