应用场景:
UITextField:比如姓名,公司,职位等,这些一般一行
UITextView:比如,个人爱好,个人简介等,多行
一般上面的这些的内容,都会需要限制字数,比如姓名5个字,个人简介100个字等。下面说说我遇到的问题和解决:
- 字数限制
- 字数统计
- 中文联想字数无法控制
- 超出部分文字裁剪掉,只能显示最大限制的字数
- 使用UITextView限制字数崩溃,或者粘贴文字崩溃,报错关于shouldChangeTextInRange
- UITextView使用类似UITextField的占位字符(placeholder)功能
UITextField:
一般限制字数很好弄,但是中文拼音的联想,即使你限制最大字数,中文联想还是能继续打字,通过查阅,代码如下:
注册通知:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFiledEditChanged:) name:@"UITextFieldTextDidChangeNotification" object:self.infoTextField];
实现方法:
- (void)textFiledEditChanged:(NSNotification *)obj
{
UITextField *textField = (UITextField *)obj.object;
NSString *toBeString = textField.text;
NSString *lang = [[UITextInputMode currentInputMode] primaryLanguage]; // 键盘输入模式
if ([lang isEqualToString:@"zh-Hans"]) { // 简体中文输入,包括简体拼音,健体五笔,简体手写
UITextRange *selectedRange = [textField markedTextRange]; //获取高亮部分
UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
// 没有高亮选择的字,则对已输入的文字进行字数统计和限制
if (!position) {
if (toBeString.length >= 7) {
textField.text = [toBeString substringToIndex:7];
}
} // 有高亮选择的字符串,则暂不对文字进行统计和限制
else{
}
} // 中文输入法以外的直接对其统计限制即可,不考虑其他语种情况
else{
if (toBeString.length >= 7) {
textField.text = [toBeString substringToIndex:7];
}
}
}
UITextView
UITextView类似UITextField的placeholder功能
用运行时,可以找到UITextView有个私有属性,key:"_placeholderLabel"
代码:
1、先搞个lable属性
@property (weak,nonatomic) UILabel *placeHolderLabel;
2、加载
- (UILabel *)placeHolderLabel
{
if (_placeHolderLabel == nil) {
UILabel *placeHolderLabel = [[UILabel alloc] init];
placeHolderLabel.text = @"我是占位字符,我高傲";
placeHolderLabel.numberOfLines = 0;
placeHolderLabel.textColor = [UIColor lightGrayColor];
placeHolderLabel.font = [UIFont systemFontOfSize:15];
[placeHolderLabel sizeToFit];
_placeHolderLabel = placeHolderLabel;
}
return _placeHolderLabel;
}
3、赋值
[self.myTextView setValue:self.placeHolderLabel forKey:@"_placeholderLabel"];
上面这些有个注意点,保持placeHolderLabel与myTextView的font字体大小一致,否则会出现跳动对不齐。输入内容和占位字符调整下距离屏幕边框的位置
self.myTextView.textContainerInset = UIEdgeInsetsMake(10, 10, 10, 10);//textview内边距,上,左,下,右-
字数限制
#pragma mark - UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
//判断加上输入的字符,是否超过界限
NSString *str = [NSString stringWithFormat:@"%@%@", textView.text, text];
if (str.length > 200)
{
textView.text = [textView.text substringToIndex:200];
return NO;
}
return YES;
}- (void)textViewDidChange:(UITextView *)textView { if (textView.text.length > 200) { textView.text = [textView.text substringToIndex:200]; } //记录输入的字数,你若不统计字数,忽略这行 self.limitWordLable.text = [NSString stringWithFormat:@"%lu/%d", (unsigned long)[textView.text length], 200]; }
这样写完看似没什么问题,UITextView不用控制中文联想,到了字数限制就不能继续显示,但是测试发现,当粘贴过来的文字大于最大限制字数就会crash
查阅资料,修改shouldChangeTextInRange的代码,textViewDidChange代码不变
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{
NSString *str = [NSString stringWithFormat:@"%@%@", textView.text, text];
if (str.length > LimitMaxWord)
{
NSRange rangeIndex = [str rangeOfComposedCharacterSequenceAtIndex:200];
if (rangeIndex.length == 1)//字数超限
{
textView.text = [str substringToIndex:200];
//这里重新统计下字数,字数超限,我发现就不走textViewDidChange方法了,你若不统计字数,忽略这行
self.wordLable.text = [NSString stringWithFormat:@"%lu/%d", (unsigned long)textView.text.length, 200];
}else{
NSRange rangeRange = [str rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, 200)];
textView.text = [str substringWithRange:rangeRange];
}
return NO;
}
return YES;
}
搞定了,粘贴文字崩溃就解决了,也做到了字数的限制。