上面说的全部 - 我将UITextField设置为安全,但是希望为用户提供使其不安全的选项(这样他们就可以确定如果他们在私有区域中输入了什么)。但是,假设他们错误地点击了切换,并希望将其更改回安全模式?这不起作用。我已经尝试了一切 - 使用-1代替YES,删除文本然后将其放回原处。我完全失去了其他想法。 [输入rdar:// 9781908]
编辑:我认为这个问题在iOS5中已经修复。
答案 0 :(得分:47)
必须是输入焦点问题:聚焦时,UITextField只能改变ON-> OFF。
尝试下一个技巧切换OFF-> ON:
textField.enabled = NO;
textField.secureTextEntry = YES;
textField.enabled = YES;
[textField becomeFirstResponder];
编辑(dhoerl):在iOS 9.3中,我发现这有效,但存在问题。如果在普通视图中输入3个字符,则切换到安全文本,然后键入字符,3个预先存在的字符将消失。我尝试了各种技巧来清除,然后重置文本但没有成功。我终于尝试通过切割和粘贴来控制控件 - 粘贴到新切换到安全模式的工作非常棒。所以我在代码中模拟它,现在一切正常 - 不需要和响应者一起玩。以下是我最终的结果:
if textview should go into secure mode and the textfield is not empty {
textField.text = ""
textField.secureTextEntry = true
UIPasteboard.generalPasteboard().string = password
textField.paste(self)
UIPasteboard.generalPasteboard().string = ""
}
我不想做这种粘贴,但如果你想要它无缝,这是我能找到它的唯一方法。
答案 1 :(得分:23)
Mike R的解决方案很好,但我更喜欢这种方法:
BOOL wasFirstResponder;
if ((wasFirstResponder = [passwordField isFirstResponder])) {
[passwordField resignFirstResponder];
}
// In this example, there is a "show password" toggle
[passwordField setSecureTextEntry:![passwordField isSecureTextEntry]];
if (wasFirstResponder) {
[passwordField becomeFirstResponder];
}
这样你只在必要时再次成为FirstResponder。
答案 2 :(得分:1)
我对这个问题进入了rdar,但确实找到了解决方法。基本上,您必须以编程方式将“卡住”控件替换为新控件。最简单的方法是将viewDidLoad中的现有控件存档,然后根据需要取消存档:
// do in viewDidLoad
self.passwordMemberArchive = [NSMutableData data];
NSKeyedArchiver *ka = [[NSKeyedArchiver alloc] initForWritingWithMutableData:passwordMemberArchive];
[ka encodeObject:password];
[ka finishEncoding];
[ka release];
// In the action method when you get the UISwitch action message ---
// when your switch changes state
if(isOn) {
NSString *text = [NSString stringWithString:password.text];
NSKeyedUnarchiver *kua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
UITextField *tf = [kua decodeObject];
[kua finishDecoding];
[kua release];
tf.inputAccessoryView = textField.inputAccessoryView;
tf.frame = textField.frame;
BOOL isFirstResponder = [textField isFirstResponder];
[scrollView insertSubview:tf aboveSubview:textField];
if(isFirstResponder) {
[tf becomeFirstResponder];
}
[textField removeFromSuperview];
self.password = tf;
if([text length]) {
if(isFirstResponder) {
// http://stackoverflow.com/questions/1317929/insert-string-at-cursor-position-of-uitextfield
// Get a reference to the system pasteboard
UIPasteboard* lPasteBoard = [UIPasteboard generalPasteboard];
// Save the current pasteboard contents so we can restore them later
NSArray* lPasteBoardItems = [lPasteBoard.items copy];
// Update the system pasteboard with my string
lPasteBoard.string = text;
// Paste the pasteboard contents at current cursor location
[tf paste:self];
// Restore original pasteboard contents
lPasteBoard.items = lPasteBoardItems;
[lPasteBoardItems release];
} else {
tf.text = text;
}
}
} else {
textField.secureTextEntry = NO;
}
答案 3 :(得分:0)
使用iOS,你永远不应该试图“破解”东西,如果你想要的行为不是由框架提供的,那就改变主意了!
首先它更容易^^,第二个用户不会对此做出响应,然后你永远不知道下一个iOS更新是否会破坏它,所以它对你的应用程序来说可能是危险的。
“您希望用户看到他在安全文本字段上录制的密码”,您可以在底部显示UILabel吗?或者是带有明确密码的确认警告框?
答案 4 :(得分:0)
桑迪解决方案的Swift版本。
if #available(iOS 9.2, *) {
passwordTextField.secureTextEntry = !passwordTextField.secureTextEntry
}
else {
let wasFirstResponder = passwordTextField.isFirstResponder()
if wasFirstResponder {
passwordTextField.resignFirstResponder()
}
passwordTextField.secureTextEntry = !passwordTextField.secureTextEntry
if wasFirstResponder {
passwordTextField.becomeFirstResponder()
}
}