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

IosSwiftUitextfield

Ios Problem Overview


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.

secure text entry

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?

Ios Solutions


Solution 1 - Ios

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

Solution 2 - Ios

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.

Solution 3 - Ios

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()

Solution 4 - Ios

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

iOS password toggle eye icons

  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 UITextField Outlet

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

Solution 5 - Ios

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()

Solution 6 - Ios

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

Solution 7 - Ios

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

Solution 8 - Ios

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

Solution 9 - Ios

Swift 3

//    MARK: Btn EyeAction
@IBAction func btnEyeAction(_ sender: Any) {
    
    if(iconClick == true) {
        txtPassword.isSecureTextEntry = false
        iconClick = false
    } else {
        txtPassword.isSecureTextEntry = true
        iconClick = true
    }
}

Solution 10 - Ios

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.

Solution 11 - Ios

This worked for me on Swift 5.0

@IBAction func changePasswordVisibility(_ sender: UIButton) {
    passwordField.isSecureTextEntry.toggle()
    if passwordField.isSecureTextEntry {
        if let image = UIImage(systemName: "eye.fill") {
            sender.setImage(image, for: .normal)
        }
    } else {
        if let image = UIImage(systemName: "eye.slash.fill") {
            sender.setImage(image, for: .normal)
        }
    }
}

Button attributes:

enter image description here

Result:

enter image description here enter image description here

Solution 12 - Ios

Swift 3

passwordTF.isSecureTextEntry = true
passwordTF.isSecureTextEntry = false

Solution 13 - Ios

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

Solution 14 - Ios

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

Solution 15 - Ios

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
}

Solution 16 - Ios

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

Solution 17 - Ios

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

this is example of

Solution 18 - Ios

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

Solution 19 - Ios

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

Solution 20 - Ios

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.

Solution 21 - Ios

For Xamarin folks:

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

Solution 22 - Ios

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)

    }

Solution 23 - Ios

@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.

Solution 24 - Ios

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)
    }
}

Solution 25 - Ios

only add this line into your code replace you TextField name with "textfield" Done: you need to change the isSecureTextEntry propertity to change true for password type textFiled like ......

textField.isSecureTextEntry = true

Solution 26 - Ios

 sender.isSelected = !sender.isSelected
    if(sender.isSelected == true) {
        RegPasswordField.isSecureTextEntry = false
        sender.setBackgroundImage(UIImage(systemName: "eye.fill"), for: .normal)
            } else {
                RegPasswordField.isSecureTextEntry = true
                sender.setBackgroundImage(UIImage(systemName: "eye"), for: .normal)
            }

Solution 27 - Ios

Swift 5 Please use this

var btnClick = true

if(btnClick == true) {
            passwordTextField.isSecureTextEntry = false
        } else {
            passwordTextField.isSecureTextEntry = true
        }
        
        btnClick = !btnClick

}

Solution 28 - Ios

var viewingPassword = true 

@IBAction func btnEyeAction(_ sender: Any) {
     passwordTF.isSecureTextEntry = viewingPassword ? false : true
     viewingPassword.toggle()
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSwiftyJDView Question on Stackoverflow
Solution 1 - IosIyyappan RaviView Answer on Stackoverflow
Solution 2 - IoszathView Answer on Stackoverflow
Solution 3 - IosSuryakant SharmaView Answer on Stackoverflow
Solution 4 - IosAimanzakiView Answer on Stackoverflow
Solution 5 - IosEugene ChybisovView Answer on Stackoverflow
Solution 6 - IosPhani SaiView Answer on Stackoverflow
Solution 7 - IosBishal GhimireView Answer on Stackoverflow
Solution 8 - IosMad BureaView Answer on Stackoverflow
Solution 9 - IosBasir AlamView Answer on Stackoverflow
Solution 10 - IostryKuldeepTanwarView Answer on Stackoverflow
Solution 11 - IosChathura MadhushankaView Answer on Stackoverflow
Solution 12 - IosChristopher LarsenView Answer on Stackoverflow
Solution 13 - IosBhadresh KathiriyaView Answer on Stackoverflow
Solution 14 - IosJayesh MiruliyaView Answer on Stackoverflow
Solution 15 - IosPaulw11View Answer on Stackoverflow
Solution 16 - IosiVarunView Answer on Stackoverflow
Solution 17 - Iossingh.jitendraView Answer on Stackoverflow
Solution 18 - IosKeshav GeraView Answer on Stackoverflow
Solution 19 - IosYagnesh DobariyaView Answer on Stackoverflow
Solution 20 - IosRavi DhorajiyaView Answer on Stackoverflow
Solution 21 - IosmegaKertzView Answer on Stackoverflow
Solution 22 - IosPramod MoreView Answer on Stackoverflow
Solution 23 - IosCoffee and WafflesView Answer on Stackoverflow
Solution 24 - IosSunil aruruView Answer on Stackoverflow
Solution 25 - IosMuhammad AhmadView Answer on Stackoverflow
Solution 26 - IosAhsanView Answer on Stackoverflow
Solution 27 - IosSrinivasan_iOSView Answer on Stackoverflow
Solution 28 - IosNaqeeb AhmedView Answer on Stackoverflow