UITextField secureTextEntry - 从YES转到NO,但是返回YES无效

时间:2011-07-15 16:11:51

标签: uitextfield

上面说的全部 - 我将UITextField设置为安全,但是希望为用户提供使其不安全的选项(这样他们就可以确定如果他们在私有区域中输入了什么)。但是,假设他们错误地点击了切换,并希望将其更改回安全模式?这不起作用。我已经尝试了一切 - 使用-1代替YES,删除文本然后将其放回原处。我完全失去了其他想法。 [输入rdar:// 9781908]

编辑:我认为这个问题在iOS5中已经修复。

5 个答案:

答案 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()
    }
}