需求:
app是做视频会议的,有个输入会议号的环节,最长为15位。在显示的地方,需要每隔3位添加一个空格
问题:
只做展示,做法很简单,但是做成可以在中间删除,会引发一系列的问题,主要都是光标位置的问题
解决方案:
//1、判断是否为数字(写在NSSting的分类里)
//判断非法字符
+ (BOOL)check_isAllow:(NSString *)content {
// 特殊字符
NSString *str =@"^[A-Za-z0-9_\\s\\u4e00-\u9fa5]+$";
NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", str];
if (![emailTest evaluateWithObject:content]) {
return NO;
}
//空格检测不出来,需单独判断
NSRange range = [content rangeOfString:@" "];
if (range.location != NSNotFound) {
return NO;
}
return YES;
}
//2、设置UITextField代理
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
//获取当前textfield的光标位置,为后续移动做准备
NSUInteger currentIndex = [textField offsetFromPosition:textField.beginningOfDocument toPosition:textField.selectedTextRange.start];
if (textField.tag == 1000) {//该textfield是放在UITableViewCell里面的,因此会有多个输入框,用tag做区分
if (string.length == 0) {//删除动作,string的长度为0
if (range.location > 0) {//防止NSRange越界
range = NSMakeRange(range.location-1, 1);
NSString *lastString = [textField.text substringWithRange:range];
currentIndex--;
if ([lastString isEqualToString:@" "]) {//检测到前面一个字符为0,多进一格
currentIndex--;
}
}
}else if (!string.check_isAllow) {//判断是否为数字
return NO;
}else {//正 常移动光标
currentIndex ++;
if (currentIndex%4 == 0) {
currentIndex ++;
}
}
}
_selectIndex = MIN(19, currentIndex);//全局记录光标
return YES;
}
//3、监听UITextField的文本变化
[[UITextField new] addTarget:self
action:@selector(makeText3Number1Space:)
forControlEvents:UIControlEventEditingChanged];
-(NSString *)makeText3Number1Space:(UITextField *)tf{
NSString *text = tf.text;
NSString *currentStr = [text stringByReplacingOccurrencesOfString:@" " withString:@""];
if (currentStr.length > 15) {
text = [currentStr substringToIndex:15];
tf.text = text;
[self textFieldDidChange:tf];
return text;
}//这里大于15位的时候,直接不进行任何操作
// 每隔3位,j插入一个空格
NSMutableString *muStr = [currentStr mutableCopy];
if (muStr.length > 3) {
int i=2;
while (i<muStr.length) {
if ((i+1)%4==0) {
[muStr insertString:@" " atIndex:i];
}
i++;
}
if (muStr.length == 4) {
[muStr deleteCharactersInRange:NSMakeRange(3, 1)];
}
text = [muStr copy];
}
if (text.length == 4) {//从@“123 4”删除成@“123 ”的时候,空格会被保留,光标后面会多个空格
text = [text stringByReplacingOccurrencesOfString:@" " withString:@""];
}
tf.text = text;
//根据全局的光标index位置,重新设置光标选中的位置
UITextPosition *targetPosition = [tf positionFromPosition:[tf beginningOfDocument] offset:_selectIndex];
[tf setSelectedTextRange:[tf textRangeFromPosition:targetPosition toPosition :targetPosition]];
return text;//返回字符串,存在model里面
}
整个流程大体就是:
1、判断输入字符——》获取光标位置——》计算
2、删空格获取string——》计算并加空格——》移动光标
未完善:
1、光标移动到号码中间时,删除空格,此时空格不会被删除,有待后续完善
2、从粘贴板copy到UITextfield的话,光标位置会错乱,不想因为监听复制事件而造成内存泄漏,暂时还没做
网友评论