【问题标题】:How to toggle a UITextField secure text entry (hide password) in Swift?如何在 Swift 中切换 UITextField 安全文本输入(隐藏密码)?
【发布时间】:2016-10-18 19:01:55
【问题描述】:

我目前有一个UITextfield,其中有一个眼睛图标,按下它应该可以打开和关闭安全文本输入。

我知道您可以在属性检查器中选中“安全文本输入”框,但如何做到这一点,以便在按下图标时切换?

【问题讨论】:

标签: ios swift uitextfield


【解决方案1】:

使用此代码,

iconClick是bool变量,或者需要其他条件检查,

var iconClick = true

眼睛动作方法:

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

        iconClick = !iconClick
    }

希望对你有帮助

【讨论】:

  • secureTextEntry 设置为 false 时,这不会将密码泄漏到自定义键盘中吗?
  • 只是一个快速更新,.secureTextEntry 现在是 .isSecureTextEntry
  • @Iyyappan Ravi 如果我有多个密码文本字段来实现相同的效果怎么办。我需要为每个密码文本字段添加单独的操作吗?如何使其通用?
  • @Prabu 将动作从多个按钮集标签设置为单独的方法,就像上面解决的方法一样,希望对您有所帮助。
  • FWIW,与其维护自己的布尔值,不如使用 isSecureTextEntry 本身。当您已经有一个可爱的布尔值时,无需创建自己的 ivar。例如。 passwordTextField.isSecureTextEntry.toggle() 然后像if passwordTextField.isSecureTextEntry { ... } else { ... } 那样更新按钮。
【解决方案2】:

这样做的一个意想不到的副作用是,如果用户切换到不安全,然后返回到安全,如果用户继续输入,现有文本将被清除。除非我们重置选定的文本范围,否则光标也可能最终出现在错误的位置。

以下是处理这些情况的实现(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
        }
    }
}

这个 sn-p 正在使用 replace(_:withText:) 函数,因为它触发了 .editingChanged 事件,这恰好在我的应用程序中很有用。只需设置text = existingText 也应该没问题。

【讨论】:

  • 太好了,这就是我要找的!
  • 你也可以做 text = nil; insertText(originalText) 而不是 deleteBackward() 技巧,它会立即在最新的 iOS 版本上显示文本选择
  • 你也可以在函数的开头做 let originalSelectedTextRange = selectedTextRange ,如果光标不在文本的末尾,保持原来的位置
  • 我在这里和那里尝试了许多解决方案,直到我找到了这个。其他所有解决方案都至少引入了一个新问题。 IMO,这是没有任何副作用的完美解决方案。
  • 我有一个问题,当我显示和隐藏密码时,它就像一个高亮动画。有什么想法吗?
【解决方案3】:

为什么要使用额外的var。在eye按钮的action方法中,如下所示

password.secureTextEntry = !password.secureTextEntry

更新

Swift 4.2(根据@ROC 评论)

password.isSecureTextEntry.toggle()

【讨论】:

  • 这里不需要额外的var,@Suryakant 发布的答案是我认为最好的答案。
  • 在swift 4.2中你可以写password.isSecureTextEntry.toggle()
【解决方案4】:

Swift 4解决方案

简单切换 isSecureTextEntry 属性不需要额外的 if 语句

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

但是当您切换 isSecureTextEntry UITextField 不会重新计算文本宽度时会出现问题,并且我们在文本右侧有额外的空间。为避免这种情况,您应该以这种方式替换文本

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

更新

斯威夫特 4.2

代替

password.isSecureTextEntry = !password.isSecureTextEntry

你可以这样做

password.isSecureTextEntry.toggle()

【讨论】:

    【解决方案5】:

    我为此编写了扩展名。提供密码切换。

    1. 首先在您的资产中添加您想要切换的图像。

    2. 为 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. 您的UITextField Outlet 上的电话分机

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

    【讨论】:

    • 很好的解决方案!我要补充的一件事是,如果您按下隐藏密码按钮然后输入更多字符,则文本字段将被清除,您必须再次开始输入。我正在将此解决方案与上述@zath 的解决方案相结合。
    • 当按你的意思按下隐藏密码按钮时,我怎样才能继续我之前输入的内容? @JTODR
    • @Ali 查看zath的解决方案:if let textRange = textRange(from: beginningOfDocument, to: endOfDocument) { replace(textRange, withText: existingText) }
    • 图标可以使用:UIImage(systemName: "eye.slash.fill") 和 UIImage(systemName: "eye.fill")
    • @Ing.Ron 爱你
    【解决方案6】:

    使用 UITextFiled rightView 显示切换按钮

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

    【讨论】:

    • 很好的答案!谢谢
    • 完美!谢谢!但这不回答问题,也不解决问题。
    【解决方案7】:

    如果您在多个地方需要具有类似功能的 TextField,最好将 UITextField 子类化,如以下示例 -

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

    之后就可以在任何ViewController中使用了,

    class ViewController: UIViewController {
    
        @IBOutlet var textField: UIShowHideTextField!
    
        override func viewDidLoad() {
            super.viewDidLoad()
            textField.becomeFirstResponder()
        }
    
    }
    

    【讨论】:

      【解决方案8】:

      对于目标 c

      在 viewdidload 方法中为 RightButton 设置图像

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

      然后为那个 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];
              }
      
          }
      }
      

      【讨论】:

        【解决方案9】:

        斯威夫特 3

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

        【讨论】:

          【解决方案10】:

          最短!

          我认为这是安全输入以及更新按钮图片的最短解决方案。

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

          根据选中状态/默认分配按钮的显示/隐藏图片,无需创建任何变量或出口。

          【讨论】:

            【解决方案11】:

            斯威夫特 3

            passwordTF.isSecureTextEntry = true
            passwordTF.isSecureTextEntry = false
            

            【讨论】:

              【解决方案12】:
              @IBAction func eye_toggle_clicked(sender: AnyObject)
              {
                  if toggleBtn.tag == 0
                  {
                      passwordTxt.secureTextEntry=true
                      toggleBtn.tag=1
                  }
                  else
                  {
                      passwordTxt.secureTextEntry=false
                      toggleBtn.tag=0
                  }
              }
              

              【讨论】:

              • 请编辑更多信息。不鼓励使用纯代码和“试试这个”的答案,因为它们不包含可搜索的内容,也没有解释为什么有人应该“试试这个”。我们在这里努力成为知识的资源。
              【解决方案13】:

              正如其他人所指出的,该属性是secureTextEntry,但您不会在UITextField 文档中找到它,因为它实际上是由UITextField 通过UITextInputTraits 协议继承的-https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/#//apple_ref/occ/intfp/UITextInputTraits/secureTextEntry

              您可以在每次点击按钮时简单地切换此值:

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

              【讨论】:

                【解决方案14】:

                试试这条线:

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

                【讨论】:

                  【解决方案15】:

                  这是你的答案,不需要任何 bool var:

                  @IBAction func showHideAction(sender: AnyObject) {
                  
                          if tfPassword.secureTextEntry{
                              tfPassword.secureTextEntry = false
                  
                          }else{
                              tfPassword.secureTextEntry = true;
                          } 
                      }
                  

                  【讨论】:

                    【解决方案16】:

                    首先您需要为不同状态(选中或正常)设置眼睛按钮的图像(可见或隐藏)

                    比连接 IBAction 并编写类似的代码

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

                    【讨论】:

                      【解决方案17】:

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

                      【讨论】:

                        【解决方案18】:

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

                        按钮属性:

                        结果:

                        【讨论】:

                          【解决方案19】:

                          分配值从 YES/NO 更改为 true/false 布尔值。

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

                          你可以试试这个代码.. 我觉得很有帮助。

                          【讨论】:

                            【解决方案20】:

                            使用带有眼睛图像的按钮
                            并制作 buttonHandler 方法
                            为值为 1 的按钮设置标签

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

                            【讨论】:

                              【解决方案21】:

                              对于 Xamarin 人:

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

                              【讨论】:

                                【解决方案22】:

                                在 swift 4 中尝试此代码,尝试在控制器中创建可重用代码。我为故事板中的按钮设置了不同的图像,如链接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)
                                
                                    }
                                

                                【讨论】:

                                  【解决方案23】:
                                  @objc func togglePasscode(){
                                  
                                     switch textfield.isSecureTextEntry{
                                        case true:
                                           textfield.isSecureTextEntry = false 
                                  
                                        case false:
                                           textfield.isSecureTextEntry = true 
                                     }
                                  }
                                  

                                  这是一个使用 Switch 语句的简单且更易读的解决方案。

                                  【讨论】:

                                  • textfield.isSecureTextEntry = !textfield.isSecureTextEntry 更短
                                  【解决方案24】:

                                  希望这是一个更简单的解决方案,而不是全局创建一个 BOOL 对象。

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

                                  【讨论】:

                                    【解决方案25】:

                                    仅将此行添加到您的代码中,将您的 TextField 名称替换为“textfield”完​​成: 您需要更改 isSecureTextEntry 属性以将密码类型 textFiled 的 true 更改为......

                                    textField.isSecureTextEntry = true
                                    

                                    【讨论】:

                                      【解决方案26】:
                                       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)
                                                  }
                                      

                                      【讨论】:

                                        猜你喜欢
                                        • 1970-01-01
                                        • 2017-02-20
                                        • 2019-12-13
                                        • 2011-09-28
                                        • 2020-11-23
                                        • 1970-01-01
                                        • 2011-12-06
                                        • 1970-01-01
                                        • 2020-12-29
                                        相关资源
                                        最近更新 更多