声明:
1.文章内容参考了网上部分博客,如涉及到版权问题,请及时联系我,我会第一时间处理。
2.文章内容是个人观点,如有错误的地方也请及时联系我,谢谢。
1.关于限制字符长度的坑
拿到需求的时候我首先想到的是使用UITextFieldDelegate
的方法- (BOOL)textField:(UITextField*)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
像这样:
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString*)string {
// text field 上实际字符长度
NSIntegerstrLength = textField.text.length - range.length + string.length;
return(strLength <= 5);
}
但是,这种方法经过实际测试,只适用于英文和符号输入,当涉及到中文输入时,这里涉及到一个概念:我叫它“高亮选中内容”。如下图:
高亮选中内容.png
上面代码中我们限制字符长度是5,但是其实当我想输入第四个汉字“瓜”时,“西门西gu”这个字符穿的长度已经是5了,然后你的代理方法就会返回NO给你,这时我们就已经不能再输入其他字符了。
经过上面的坑之后,我在网上浏览的很多博客,找到了下面正确的方法(使用UITextFieldTextDidChangeNotification
通知):
限制字符长度的正确方法:
1.添加通知
// 添加监听
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textViewEditChanged:) name:UITextFieldTextDidChangeNotification object:nil];
注意:添加监听后记得移除。
2.实现监听方法
/**
* 当 text field 文本内容改变时 会调用此方法
*
* @param notification
*/
-(void)textViewEditChanged:(NSNotification *)notification{
// 拿到文本改变的 text field
UITextField *textField = (UITextField *)notification.object;
// 需要限制的长度
NSUInteger maxLength = 0;
if (textField.tag == 101) { // 中文名字限制长度
maxLength = 5;
}
if (textField.tag == 102) { // 英文名限制长度
maxLength = 10;
}
if (maxLength == 0) return;
// text field 的内容
NSString *contentText = textField.text;
// 获取高亮内容的范围
UITextRange *selectedRange = [textField markedTextRange];
// 这行代码 可以认为是 获取高亮内容的长度
NSInteger markedTextLength = [textField offsetFromPosition:selectedRange.start toPosition:selectedRange.end];
// 没有高亮内容时,对已输入的文字进行操作
if (markedTextLength == 0) {
// 如果 text field 的内容长度大于我们限制的内容长度
if (contentText.length > maxLength) {
// 截取从前面开始maxLength长度的字符串
// textField.text = [contentText substringToIndex:maxLength];
// 此方法用于在字符串的一个range范围内,返回此range范围内完整的字符串的range
NSRange rangeRange = [contentText rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, maxLength)];
textField.text = [contentText substringWithRange:rangeRange];
}
}
}
上面这段代码中,一开始在截取字符串时我使用的是substringToIndex
,但是我们可能会遇到emoji表情无法正确显示的问题,如下图:
当我们用substringToIndex
这个方法时,在我们输入的第5个字符是emoji表情时,就可能会像上图显示的那样。
在苹果认为汉字和英文字母的长度是1,而emoji表情的长度是2,就类似于你可以直接在QQ输入栏里输入“/shd”当做“闪电”表情使用。所以当我们以为我们截取的是“西门西瓜/shd”,其实我们只截取了“西门西瓜/”。
而当我们使用rangeOfComposedCharacterSequencesForRange
时,就可以避免这种情况发生。
rangeOfComposedCharacterSequencesForRange
这个方法就像我在上面注释的一样,它可以保证你range范围内字符串的完整性。所以我们先用这个方法取到完整的字符串的range,然后用substringWithRange
取到我们想要的字符串。
网友评论