我出现这个问题是在注册登录页面。该页面有一个普通的UITextField,和一个属性secureTextEntry为YES的输入密码的UITextField。因为我这里没有使用UITextField的placeholder属性,而是在UITextField上放一个label来显示提示语,这样,UITextField的退格变清空问题就会更明显。问题重现如下:
1)点击普通的UITextField输入内容
2)点击输入密码的UITextField输入内容
3)再次点击普通的UITextField获取焦点
4)再点击输入密码的UITextField,接着点击退格键,内容清空,并且提示语label不显示
经查阅,后找到了解决办法:
在UITextField的代理方法
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;中,截获退格键删除行为,让它每点一次退格键删除时只允许删除一个字符。该代理方法是在UITextField的内容改变时调用,第二个参数表明内容改变的范围,第三个参数是替代的字符串。
该解决方法的思路是,先取到光标位置,把文本内容暂存,清空原来UITextField的内容,然后将暂存的文本内容中光标左侧的文字replace掉重新赋给UITextField,并回复光标位置。以下蓝色部分的为该实现代码
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string;
{
if ([string isEqualToString:@"\n"])
{
return YES;
}
NSString * toBeString = [textField.text stringByReplacingCharactersInRange:range withString:string];
switch (textField.tag) {
case phoneNumTextFieldTag:{
if ([toBeString length] > 0) {
phoneNumReminder.hidden = YES;
} else {
phoneNumReminder.hidden = NO;
}
if ([toBeString length] > 11) {
textField.text = [toBeString substringToIndex:11];
return NO;
}
break;
}
case passwordTextFieldTag:{
if ([toBeString length] > 0) {
pwdReminder.hidden = YES;
} else {
pwdReminder.hidden = NO;
}
if ([toBeString length] > 16) {
textField.text = [toBeString substringToIndex:16];
return NO;
}
<span style="color:#3366ff;">if (range.location > 0 && range.length == 1 && string.length == 0)
{
// Stores cursor position
UITextPosition *beginning = textField.beginningOfDocument;
UITextPosition *start = [textField positionFromPosition:beginning offset:range.location];
NSInteger cursorOffset = [textField offsetFromPosition:beginning toPosition:start] + string.length;
// Save the current text, in case iOS deletes the whole text
NSString *text = textField.text;
// Trigger deletion
[textField deleteBackward];
// iOS deleted the entire string
if (textField.text.length != text.length - 1)
{
textField.text = [text stringByReplacingCharactersInRange:range withString:string];
// Update cursor position
UITextPosition *newCursorPosition = [textField positionFromPosition:textField.beginningOfDocument offset:cursorOffset];
UITextRange *newSelectedRange = [textField textRangeFromPosition:newCursorPosition toPosition:newCursorPosition];
[textField setSelectedTextRange:newSelectedRange];
}
return NO;
}</span>
break;
}
case CountryCodeTextFieldTag:{
if ([toBeString length] < 1) {
textField.text = @"+";
return NO;
} else if ([toBeString length] > 5) {
textField.text = [toBeString substringToIndex:5];
return NO;
} else {
// FLOG(@"%@",[toBeString substringFromIndex:1]);
if ([jsonNumAreaData objectForKey:[toBeString substringFromIndex:1]]) {
countryNameLabel.text = [jsonNumAreaData objectForKey:[toBeString substringFromIndex:1]];
}else{
countryNameLabel.text = NSLocalizedString(@"countryCodeError", nil);
}
}
break;
}
}
return YES;
}