UITextField secureTextEntry - works going from YES to NO, but changing back to YES has no effect

前端 未结 5 1792
无人及你
无人及你 2021-01-31 09:13

The above says it all- I have a UITextField set to secure, but want to give users the option to make it not secure (so they can see for sure what they typed if they are in a pri

相关标签:
5条回答
  • 2021-01-31 09:58

    With iOS, you should never try to "hack" stuff, if the behavior you want is not provided by the framework, change your mind !

    First its easier ^^, second the user will not be responsive to this, then you never know if the next iOS update will break it or not, so it can be dangerous for your application.

    "You want the user sees the password he is taping on a secured textfield", you can display a UILabel in the bottom instead ? Or a confirmation Alert box with the clear password ?

    0 讨论(0)
  • 2021-01-31 10:00

    I entered rdar against this problem, but did find a work around. Essentially you have to programmatically replace the "stuck" control with a new one. The easiest thing to do is to archive the existing control in viewDidLoad then unarchive as needed:

    // 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;
    }
    
    0 讨论(0)
  • 2021-01-31 10:07

    Swift version of Sandy's solution.

    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()
        }
    }
    
    0 讨论(0)
  • 2021-01-31 10:11

    Mike R's solution is nice, but I prefer this approach:

    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];
    }
    

    That way you only becomeFirstResponder again when necessary.

    0 讨论(0)
  • 2021-01-31 10:14

    It must be input-focus issue: when focused, UITextField can change only ON->OFF.
    Try next trick to switch OFF->ON:

    textField.enabled = NO;
    textField.secureTextEntry = YES;
    textField.enabled = YES;
    [textField becomeFirstResponder];
    

    EDIT (dhoerl): In iOS 9.3, I found this works but there is a problem. If you enter say 3 characters in plain view, then switch to secure text, then type a character, the 3 pre-existing characters disappear. I tried all kinds of trick to clear, then reset the text without success. I finally tried just playing with the control by cutting and pasting - pasting into the newly-switched-to-secure-mode worked great. So I emulated it in code, and now it all works fine - no need to play with the responder either. Here is what I finally ended up with:

        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 = ""
        }
    

    I'd prefer to not have to do this paste, but if you want it seamless this is the only way I can find to do it.

    0 讨论(0)
提交回复
热议问题