我正在使用XCode和Objective-C开发iPad应用程序。我有一个UI,其中包括密码输入字段和显示/隐藏按钮(代码如下所示)。测试人员指出了以下不一致的行为。
如果密码被隐藏并且输入了一半(例如" abc")并且用户点击切换按钮以显示密码并继续键入然后输入新字符(例如" def&#34 ;)被添加到初始条目的末尾(制作" abcdef")。一切都很好。
但是,如果显示密码并输入一半(例如" abc")并且用户点击切换按钮隐藏密码并继续输入新字符(例如" def& #34;)替换初始条目(制作" def")。因此,显示/隐藏切换不仅会显示或隐藏文本,还会在输入下一个字符时更改UITextField的行为(追加/清除并重新开始)。
我可以想到(不是很好)这种行为是出于设计的原因,但没有人能够证明它是好的。任何人都可以建议快速修复(这可以防止切换隐藏文本操作清除部分输入的密码)?
- (IBAction)togglePasswordReveal:(id)sender
{
if ([self.revealButton.titleLabel.text isEqualToString:@"Show"]) {
self.password.secureTextEntry = NO;
[self.revealButton setTitle:@"Hide" forState:UIControlStateNormal];
}
else {
self.password.secureTextEntry = YES;
[self.revealButton setTitle:@"Show" forState:UIControlStateNormal];
}
}
答案 0 :(得分:2)
我无法找到相关文档,但我记得更改安全条目设置也会更改clearsOnInsertion
。
查看设置clearsOnInsertion
和/或使用委托方法textFieldShouldClear:
和textField:shouldChangeCharactersInRange:replacementString:
来修改此行为。
我猜逻辑是用户通常不会确定他们之前键入的内容,因为他们无法看到字符,所以sage选项是强制用户重新开始。
答案 1 :(得分:1)
面临同样的问题。这是我的理解和解决方案。
更改clearsOnInsertion,clearsOnBeginEditing对安全文本字段没有影响。
在文本字段上切换secureTextEntry会导致它失去响应者状态并再次成为第一响应者。因此,任何新文本都会清除当前文本。
出于安全原因,我通过覆盖textField:shouldChangeCharactersInRange:replacementString:
和其他一些更改解决了这个问题。我在编辑时使用右视图显示切换按钮。
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
// Customize text entry in password field
if (textField == self.passwordTf) {
NSString *currentString = textField.text;
// Handle inserting, deleting characters
textField.text = [currentString stringByReplacingCharactersInRange:range withString:string];
// Setting the cursor at the right place
NSRange selectedRange = NSMakeRange(range.location + string.length, 0);
UITextPosition* from = [textField positionFromPosition:textField.beginningOfDocument offset:selectedRange.location];
UITextPosition* to = [textField positionFromPosition:from offset:selectedRange.length];
textField.selectedTextRange = [textField textRangeFromPosition:from toPosition:to];
// If password cleared, updated edited status
if (textField.text.length == 0) {
passwordEdited = YES;
}
[self toggleButtonStatus];
return NO;
}
return YES;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
// Reset password edited status on begin editing
if (textField == self.passwordTf &&
[textField.text length] > 0) {
passwordEdited = NO;
}
[self toggleButtonStatus];
}
- (void)textFieldDidChange:(NSNotification*)notification
{
UITextField *textField = notification.object;
// If password cleared, updated edited status
if (self.passwordTf == textField &&
textField.text.length == 0) {
passwordEdited = YES;
}
[self toggleButtonStatus];
}
- (void)toggleButtonStatus
{
// For security, only show eye button if not saved password
if (passwordEdited) {
self.passwordTf.clearButtonMode = UITextFieldViewModeNever;
self.passwordTf.rightViewMode = UITextFieldViewModeWhileEditing;
} else {
self.passwordTf.clearButtonMode = UITextFieldViewModeWhileEditing;
self.passwordTf.rightViewMode = UITextFieldViewModeNever;
}
}
作为奖励,这里是切换按钮的代码,在切换时更新光标位置。
eyeButton = [UIButton buttonWithType:UIButtonTypeCustom];
eyeButton.frame = CGRectMake(0, 0, 44, 44);
eyeButton.imageEdgeInsets = UIEdgeInsetsMake(0, 16, 0, 0);
[eyeButton addTarget:self action:@selector(eyeButtonPressed:) forControlEvents:UIControlEventTouchDown];
[eyeButton addTarget:self action:@selector(eyeButtonReleased:) forControlEvents:UIControlEventTouchUpInside];
[eyeButton addTarget:self action:@selector(eyeButtonReleased:) forControlEvents:UIControlEventTouchUpOutside];
[eyeButton addTarget:self action:@selector(eyeButtonReleased:) forControlEvents:UIControlEventTouchCancel];
[eyeButton addTarget:self action:@selector(eyeButtonReleased:) forControlEvents:UIControlEventTouchDragExit];
...
self.passwordTf.rightView = eyeButton;
self.passwordTf.rightViewMode = UITextFieldViewModeWhileEditing;
- (void)eyeButtonPressed:(id)sender {
UIFont *textFieldFont = ...
UIColor *textFieldColor = ...
// Hack to update cursor position
self.passwordTf.defaultTextAttributes = @{NSFontAttributeName: textFieldFont,
NSForegroundColorAttributeName: textFieldColor};
// Change secure entry
self.passwordTf.secureTextEntry = NO;
}
- (void)eyeButtonReleased:(id)sender {
UIFont *textFieldFont = ...
UIColor *textFieldColor = ...
// Hack to update cursor position
self.passwordTf.defaultTextAttributes = @{NSFontAttributeName: textFieldFont,
NSForegroundColorAttributeName: textFieldColor};
// Change secure entry
self.passwordTf.secureTextEntry = YES;
}
如果您需要任何澄清或发现任何错误,请与我们联系。 ;) 享受!