【问题标题】:iOS 12 Suggested strong password textfield delegate callback for Choose My Own PasswordiOS 12 建议选择我自己的密码的强密码文本字段委托回调
【发布时间】:2019-05-03 03:25:15
【问题描述】:

在 iOS 12 中,我有一个用于注册流程的新密码文本字段,我希望系统建议一个强密码。我还有一个基于委托方法启用和禁用的按钮,我做了一些更改等。

textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String)

这对于在用户点击Use Strong Password 时启用它很有用。 但是,当用户可能点击 Choose My Own Password 时,我似乎没有收到委托回调,因此我的按钮启用/禁用逻辑永远没有机会执行,从而允许某人使用空白密码进行注册。

关于当用户点击Choose my own password 时我可能无法获得回调的任何想法?非常感谢任何帮助。

【问题讨论】:

    标签: ios swift uitextfield ios12


    【解决方案1】:

    我遇到了同样的问题,但我发现唯一提供回调的是 UIViewviewDidLayoutSubviews 代表

    所以我所做的就是使用这个:

    override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
            if passwordTextField.isFirstResponder {
               validatePassword(passwordTextField.text ?? "")
            }
        }
    

    【讨论】:

      【解决方案2】:

      iOS 13 引入了新的委托方法

      func textFieldDidChangeSelection(_ textField: UITextField) {
      
      }
      

      当强密码被填写和删除时调用。同样,它仅在 iOS 13 中可用。

      当文本更改或被清除时也会调用它,因此请注意,如果您正在调用 shouldChangeCharactersIn 或使用 UIControl.Event.editingChanged 添加操作,这两种方法都会响应

      【讨论】:

        【解决方案3】:

        我不熟悉“使用字符串密码”的委托,但如果用户选择自己的密码,您需要检查用户在密码文本字段中输入的内容并验证它是否符合您的条件。

        为此,您需要使用目标.editingChanged 检查在密码文本字段中输入的内容。当用户键入其中的任何内容时,将启用或禁用该按钮。查看第 3 步和第 4 步。第 4 步将切换并决定启用或禁用按钮。

        要注意的另一件事是,当 vc 首次出现时,按钮应为disabled,然后一旦密码 textField 数据有效,然后启用按钮。第 1 步和第 4 步

        例如,在我的应用程序中,如果用户在密码文本字段内的所有空格中输入,则注册按钮将被禁用,但如果他们输入有效数据,则该按钮将被启用。

        更新我随后在viewDidLoad 的步骤 3A 和 3B 中添加,因为正如 @DawsonToth 在 cmets 中正确指出的那样,如果用户选择了强密码,则将启用下一步按钮。但是,如果他们随后决定选择选择我自己的密码,passwordTextField 将清除,但仍会启用下一个按钮。我没有考虑到这一点。

        您需要将KVO observer 添加到passwordTextField 的“文本”keypath 中,这样每次passwordTextField 的文本更改时都会调用handleTextInputChanged(),从而在清除文本后禁用下一个按钮。

        // 1. create a signUp button and make sure it is DISABLED and the color is .lightGray to signify that. In step 4 if the data inside the passwordTextField is valid I enable then button and change the color to blue
        let signUpButton: UIButton = {
            let button = UIButton(type: .system)
            button.isEnabled = false // ** this must be set as false otherwise the user can always press the button **
            button.setTitle("SignUp", for: .normal)
            button.setTitleColor(UIColor.white, for: .normal)
            button.backgroundColor = UIColor.lightGray
            button.addTarget(self, action: #selector(signUpButtonTapped), for: .touchUpInside)
            return button
        }()
        
        // 2. create the password textField and set its delegate in viewDidLoad. For eg self.passwordTextField.delegate = self
        let passwordTextField: UITextField = {
            let textField = UITextField()
            textField.placeholder = "Enter Password"
            textField.autocapitalizationType = .none
            textField.returnKeyType = .done
            textField.isSecureTextEntry = true
        
            // 3. add the target for .editingChanged to check the textField
            textField.addTarget(self, action: #selector(handleTextInputChanged), for: .editingChanged)
            return textField
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
        
            passwordTextField.delegate = self // if this is programmatic make sure to add UITextFieldDelegate after the class name
        
            // 3A. Add a KVO observer to the passwordTextField's "text" keypath
            passwordTextField.addObserver(self, forKeyPath: "text", options: [.old, .new], context: nil)
        }
        
        // 3B. call the observer
        override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
            if keyPath == "text" {
                handleTextInputChanged()
            }
        }
        // 4. this checks what's typed into the password textField from step 3
        @objc fileprivate func handleTextInputChanged() {
        
            let isFormValid = !isPasswordTextFieldIsEmpty() // if the textField ISN'T empty then the form is valid
        
            if isFormValid {
        
                signUpButton.isEnabled = true
                signUpButton.backgroundColor = .blue
            } else {
        
               signUpButton.isEnabled = false
               signUpButton.backgroundColor = .lightGray
            }
        }
        
        // 5. create a function to check to see if the password textField is empty
        func isPasswordTextFieldIsEmpty() -> Bool {
        
            // 6. this checks for blank space
            let whiteSpace = CharacterSet.whitespaces
        
            // 7. if the passwordTextField has all blank spaces in it or is empty then return true
            if passwordTextField.text!.trimmingCharacters(in: whitespace) == "" || passwordTextField.text!.isEmpty {
                return true
            }
            return false // if it has valid characters in it then return false
        }
        
        // 8. target method from step 1
        @objc func signUpButtonTapped() {
            // run firebase code
        }
        

        【讨论】:

        • 投了反对票,因为您似乎没有仔细阅读该问题。 OP 已经在按照您的建议进行操作。他们的问题是,在一个非常特殊的情况下,委托没有被调用。另一个答案解决了这个问题。
        • @DawsonToth 显然您完全没有阅读答案。我说的第一句话是“我对代表不熟悉……”我给出的是 op 的替代方案。如果您查看提出问题的日期与我回答问题的日期与发布另一个答案的日期,您会发现整整一个月过去了,没有人回答问题。你对答案投了反对票,因为当一个不存在的时候我给出了一个替代方案。帮助人们摆脱困境会适得其反。
        • 我确实读过它,我明白。这不是私人的。它如何下降的时间表对我来说非常有意义。然而,对于阅读问答的人来说,当前状态才是最重要的,而不是我们如何到达那里。您的回答没有解决围绕强密码不触发更改事件的核心问题。您的答案将显示与原始问题想要解决的相同错误。因此,您的答案不完整,会导致用户误入歧途,并且不能充分回答问题。这就是我投反对票的原因,以确保阅读的人更有可能使用其他答案。
        • @DawsonToth 2 分反对票并没有什么不同,但最初看起来你确实在拖钓,所以这就是我这样回应的原因。但另一方面,我注意到 stackoverflow 的一件事是有时问题得到零响应,有时人们遇到与操作相同的问题,他们需要任何可以工作的东西。如果答案的代码有问题,那么是的,它应该被否决。但是,如果它可以替代没有答案的问题,那么它仍然可以帮助某人完成他们的项目。我想这是有待商榷的。无论如何,享受你的一天,干杯!
        • @DawsonToth 你是 100% 正确的,我忘了在我的回答中说明这一点。我会以不同的方式解决问题。我会在密码文本字段的 keypath == “text” 上添加一个 KVO,然后调用 handleTextInputChanged,这样一旦文本字段的文本被清除,它就会触发。我更新了答案并承认您指出了我的错误。感谢您向我指出这一点?
        【解决方案4】:

        我遇到了同样的问题。我所做的只是计算文本字段的子视图。

        if textField.subviews.count == 3 { } // Has suggested password
        

        我做这个检查

          @objc func textFieldDidChange(_ textField: UITextField)
        

        【讨论】:

          【解决方案5】:

          我遇到了同样的问题。

          我通过监听onEndEditing 事件跳过它以更新状态。

          <Input value={this.state.val} 
            onChangeText={(val) => this.setState({val})} 
            secureTextEntry={true} 
            onEndEditing={(e)=>{this.setState({val : e.nativeEvent.text)}}/>

          【讨论】:

            猜你喜欢
            • 2019-03-10
            • 1970-01-01
            • 2020-05-12
            • 1970-01-01
            • 2021-08-02
            • 2017-06-08
            • 2021-10-29
            • 1970-01-01
            • 2017-01-27
            相关资源
            最近更新 更多