How to toggle a UITextField secure text entry (hide password) in Swift?

喜夏-厌秋 提交于 2020-07-31 06:18:49

问题


I currently have a UITextfield with an eye icon in it that when pressed is supposed to toggle the secure text entry on and off.

I know you can check mark the "secure text entry" box in the attributes inspector but how to do it so it toggles whenever the icon is pressed?


回答1:


Use this code,

iconClick is bool variable, or you need other condition check it,

var iconClick = true

eye Action method:

@IBAction func iconAction(sender: AnyObject) {
        if(iconClick == true) {
            passwordTF.secureTextEntry = false
        } else {
            passwordTF.secureTextEntry = true
        }

        iconClick = !iconClick
    }

hope its helpful




回答2:


An unintended side-effect of this is that if the user toggles to insecure, and then back to secure, the existing text will be cleared if the user continues typing. The cursor may also end up in the wrong position unless we reset the selected text range.

Below is an implementation that handles these cases (Swift 4)

extension UITextField {
    func togglePasswordVisibility() {
        isSecureTextEntry = !isSecureTextEntry

        if let existingText = text, isSecureTextEntry {
            /* When toggling to secure text, all text will be purged if the user 
             continues typing unless we intervene. This is prevented by first 
             deleting the existing text and then recovering the original text. */
            deleteBackward()

            if let textRange = textRange(from: beginningOfDocument, to: endOfDocument) {
                replace(textRange, withText: existingText)
            }
        }

        /* Reset the selected text range since the cursor can end up in the wrong
         position after a toggle because the text might vary in width */
        if let existingSelectedTextRange = selectedTextRange {
            selectedTextRange = nil
            selectedTextRange = existingSelectedTextRange
        }
    }
}

This snippet is using the replace(_:withText:) function because it triggers the .editingChanged event, which happens to be useful in my application. Just setting text = existingText should be fine as well.




回答3:


Why to use an extra var. In the action method of the eye button just do as below

password.secureTextEntry = !password.secureTextEntry

UPDATE

Swift 4.2 (as per @ROC comment)

password.isSecureTextEntry.toggle()



回答4:


Swift 4 solution

You don't need extra if statement for simple toggle isSecureTextEntry property

func togglePasswordVisibility() {
        password.isSecureTextEntry = !password.isSecureTextEntry
    }

But there is a problem when you toggle isSecureTextEntry UITextField doesn't recalculate text width and we have extra space to the right of the text. To avoid this you should replace text this way

func togglePasswordVisibility() {
        password.isSecureTextEntry = !password.isSecureTextEntry
        if let textRange = password.textRange(from: password.beginningOfDocument, to: password.endOfDocument) {
            password.replace(textRange, withText: password.text!)
        }
    }

UPDATE

Swift 4.2

Instead of

password.isSecureTextEntry = !password.isSecureTextEntry

you can do this

password.isSecureTextEntry.toggle()



回答5:


Use UITextFiled rightView to show toggle button

 var rightButton  = UIButton(type: .custom)
 rightButton.frame = CGRect(x:0, y:0, width:30, height:30)
 yourtextfield.rightViewMode = .always
 yourtextfield.rightView = rightButton



回答6:


For Objective c

set image for RightButton In viewdidload Method

[RightButton setImage:[UIImage imageNamed:@"iconEyesOpen"] forState:UIControlStateNormal];

    [RightButton setImage:[UIImage imageNamed:@"iconEyesClose"] forState:UIControlStateSelected];

and then set action method for that RightButton

-(IBAction)RightButton:(id)sender
{

    if (_rightButton.selected)
    {

        _rightButton.selected = NO;

        _passwordText.secureTextEntry = YES;


        if (_passwordText.isFirstResponder) {
            [_passwordText resignFirstResponder];
            [_passwordText becomeFirstResponder];
        }
    }
    else
    {

      _rightButton.selected = YES;

        _passwordText.secureTextEntry = NO;

        if (_passwordText.isFirstResponder) {
            [_passwordText resignFirstResponder];
            [_passwordText becomeFirstResponder];
        }

    }
}



回答7:


If you need TextField with similar feature in multiple places its best to subclass the UITextField like follwing example -

import UIKit

class UIShowHideTextField: UITextField {

    let rightButton  = UIButton(type: .custom)

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        commonInit()
    }

    required override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }

    func commonInit() {
        rightButton.setImage(UIImage(named: "password_show") , for: .normal)
        rightButton.addTarget(self, action: #selector(toggleShowHide), for: .touchUpInside)
        rightButton.frame = CGRect(x:0, y:0, width:30, height:30)

        rightViewMode = .always
        rightView = rightButton
        isSecureTextEntry = true
    }

    @objc
    func toggleShowHide(button: UIButton) {
        toggle()
    }

    func toggle() {
        isSecureTextEntry = !isSecureTextEntry
        if isSecureTextEntry {
            rightButton.setImage(UIImage(named: "password_show") , for: .normal)
        } else {
            rightButton.setImage(UIImage(named: "password_hide") , for: .normal)
        }
    }

}

After which you can use it in any ViewController,

class ViewController: UIViewController {

    @IBOutlet var textField: UIShowHideTextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.becomeFirstResponder()
    }

}



回答8:


Swift 3

//    MARK: Btn EyeAction
@IBAction func btnEyeAction(_ sender: Any) {

    if(iconClick == true) {
        txtPassword.isSecureTextEntry = false
        iconClick = false
    } else {
        txtPassword.isSecureTextEntry = true
        iconClick = true
    }
}



回答9:


Swift 3

passwordTF.isSecureTextEntry = true
passwordTF.isSecureTextEntry = false



回答10:


@IBAction func eye_toggle_clicked(sender: AnyObject)
{
    if toggleBtn.tag == 0
    {
        passwordTxt.secureTextEntry=true
        toggleBtn.tag=1
    }
    else
    {
        passwordTxt.secureTextEntry=false
        toggleBtn.tag=0
    }
}



回答11:


As others have noted, the property is secureTextEntry, but you won't find this in the UITextField documentation, as it is actually inherited by a UITextField through the UITextInputTraits protocol- https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/#//apple_ref/occ/intfp/UITextInputTraits/secureTextEntry

You can simply toggle this value each time your button is tapped:

@IBAction func togglePasswordSecurity(sender: UIButton) {
    self.passwordField.secureTextEntry = !self.passwordField.secureTextEntry
}



回答12:


try this line:

@IBAction func btnClick(sender: AnyObject) {
    let btn : UIButton = sender as! UIButton
    if btn.tag == 0{
        btn.tag = 1
        textFieldSecure.secureTextEntry = NO
    }
    else{
        btn.tag = 0
        textFieldSecure.secureTextEntry = NO;
    }
}



回答13:


Here is your answer no need to take any bool var:

@IBAction func showHideAction(sender: AnyObject) {

        if tfPassword.secureTextEntry{
            tfPassword.secureTextEntry = false

        }else{
            tfPassword.secureTextEntry = true;
        } 
    }



回答14:


First you need to set image(visible or hide) of button of eye for different state (selected or normal)

than connect IBAction and write code like

@IBAction func btnPasswordVisiblityClicked(_ sender: Any) {
        (sender as! UIButton).isSelected = !(sender as! UIButton).isSelected
        if (sender as! UIButton).isSelected {
            txtfPassword.isSecureTextEntry = false
        } else {
            txtfPassword.isSecureTextEntry = true
        }
    }




回答15:


In Swift 4

 var iconClick : Bool!

    override func viewDidLoad() {
        super.viewDidLoad()
        iconClick = true
     }


    @IBAction func showHideAction(_ sender: Any)
    {
        let userPassword = userPasswordTextFiled.text!;

        if(iconClick == true) {
            userPasswordTextFiled.isSecureTextEntry = false
            iconClick = false
        } else {
            userPasswordTextFiled.isSecureTextEntry = true
            iconClick = true
        }

}



回答16:


Shortest!

I think this is the shortest solution for secure entry as well as updating the picture of the button.

@IBAction func toggleSecureEntry(_ sender: UIButton) {
    sender.isSelected = !sender.isSelected
    textfieldPassword.isSecureTextEntry = !sender.isSelected
}

Assign the show/hide picture of the button according to the state selected /default , no need to create any variable or outlet.




回答17:


Assignment values change from YES/NO to true/false boolean values.

password.secureTextEntry = true //Visible
password.secureTextEntry = false //InVisible

You can try this code.. i think it's helpful.




回答18:


Use button with eye image
and make buttonHandler method
set Tag for button with value 1

-(IBAction) buttonHandlerSecureText:(UIButton *)sender{
      if(sender.tag ==1){
            [self.textField setSecureTextEntry:NO];
            sender.tag = 2;
      }
      else{
            [self.textField setSecureTextEntry:YES];
            sender.tag = 1;
      }
}



回答19:


For Xamarin folks:

passwordField.SecureTextEntry = passwordField.SecureTextEntry ? passwordField.SecureTextEntry = false : passwordField.SecureTextEntry = true;




回答20:


Try this code in swift 4, tried to make a reusable code within a controller. I have set different image for buttons in storyboard as shown in the link https://stackoverflow.com/a/47669422/8334818

@IBAction func clickedShowPassword(_ sender: UIButton) {
        var textField :UITextField? = nil
        print("btn ",sender.isSelected.description)
        switch sender {
        case encryptOldPswdBtn:
            encryptOldPswdBtn.isSelected = !encryptOldPswdBtn.isSelected
            textField = oldPasswordTextField

        default:
          break
        }

        print("text ",textField?.isSecureTextEntry.description)
        textField?.isSecureTextEntry = !(textField?.isSecureTextEntry ?? false)

    }



回答21:


@objc func togglePasscode(){

   switch textfield.isSecureTextEntry{
      case true:
         textfield.isSecureTextEntry = false 

      case false:
         textfield.isSecureTextEntry = true 
   }
}

Here is a easy and more readable solution using Switch statement.




回答22:


Hope this is simpler solution rather than creating a BOOL object globally.

@IBAction func passwordToggleButton(sender: UIButton) {
    let isSecureTextEntry = passwordTextField.isSecureTextEntry
    passwordTextField.isSecureTextEntry = isSecureTextEntry ? false : true
    if isSecureTextEntry {
        visibilityButton.setImage(UIImage(named: "visibility"), for: .normal)
    } else {
        visibilityButton.setImage(UIImage(named: "visibility_off"), for: .normal)
    }
}



回答23:


I wrote extension for the same. To provide Password toggle.

  1. In your Assets first add images that you want for toggle.

  2. Add following Extension for UITextField.

    extension UITextField {
    fileprivate func setPasswordToggleImage(_ button: UIButton) {
        if(isSecureTextEntry){
            button.setImage(UIImage(named: "ic_password_visible"), for: .normal)
        }else{
            button.setImage(UIImage(named: "ic_password_invisible"), for: .normal)
    
        }
    }
    
    func enablePasswordToggle(){
        let button = UIButton(type: .custom)
        setPasswordToggleImage(button)
        button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0)
        button.frame = CGRect(x: CGFloat(self.frame.size.width - 25), y: CGFloat(5), width: CGFloat(25), height: CGFloat(25))
        button.addTarget(self, action: #selector(self.togglePasswordView), for: .touchUpInside)
        self.rightView = button
        self.rightViewMode = .always
    }
    @IBAction func togglePasswordView(_ sender: Any) {
        self.isSecureTextEntry = !self.isSecureTextEntry
        setPasswordToggleImage(sender as! UIButton)
    }
    }
    
  3. Call extension on your UITextView Outlet

     override func viewDidLoad() {
                 super.viewDidLoad()
                 txtPassword.enablePasswordToggle()
                 txtConfirmPassword.enablePasswordToggle()
             }
    


来源:https://stackoverflow.com/questions/37873119/how-to-toggle-a-uitextfield-secure-text-entry-hide-password-in-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!