如何检测用户何时在UITextField上使用密码自动填充

Mit*_*hen 10 autofill uitextfield ios uitextfielddelegate

我已经实现了在iOS 11上支持密码自动填充所需的所有应用和服务器更改,并且它运行良好.我希望它能更好一点.

我的用户名和密码字段是UITextFields.我想确定用户何时"自动填充"了两个UITextField中的一个,因此我可以进入下一步.目前用户自动填充项目,然后需要按下屏幕键盘上的"下一步"按钮才能前进.我想代表用户触发这个.

WWDC2017密码自动填充会话说使用UITextFieldTextDidChange.这有效,但当然用户手动输入这些字段时也会触发此操作.

我的想法是将文本的先前版本与文本的新版本进行比较,并假设如果长度从零增加到大于某个最小长度(2或更多),则用户使用自动填充.这应该在大多数情况下都有效,但是存在错误触发的风险(也许在慢速设备上快速输入).所以对我来说,这可能是一个冒险的假设.

我很好奇是否有人找到了更加确定的方法来确定密码自动填充是否已在UITextField上使用,或者只是认为我对错误触发的担心是没有根据的.

Rob*_*rty 9

不确定之前的答案是否在某个时候停止工作,但我无法让它工作 -didBeginEditing在使用自动填充时我只接到一个电话。

但是,我确实找到了一种检测自动填充的方法。请记住,在输入某些字符后可以使用自动填充,例如,如果用户已经在电话号码中输入了一些数字,则他们会自动填充完整的号码。

对于 Swift 4/5:

private var fieldPossibleAutofillReplacementAt: Date?

private var fieldPossibleAutofillReplacementRange: NSRange?

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    // To detect AutoFill, look for two quick replacements. The first replaces a range with a single space
    // (or blank string starting with iOS 13.4).
    // The next replaces the same range with the autofilled content.
    if string == " " || string == "" {
        self.fieldPossibleAutofillReplacementRange = range
        self.fieldPossibleAutofillReplacementAt = Date()
    } else {
        if fieldPossibleAutofillReplacementRange == range, let replacedAt = self.fieldPossibleAutofillReplacementAt, Date().timeIntervalSince(replacedAt) < 0.1 {
            DispatchQueue.main.async {
                // Whatever you use to move forward.
                self.moveForward()
            }
        }
        self.fieldPossibleAutofillReplacementRange = nil
        self.fieldPossibleAutofillReplacementAt = nil
    }

    return true
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*Dan 6

找到了解决方案。

当密码管理器用于自动填充用户名+密码时,它将触发didBeginEditing两次,速度比人类更快。

因此,我计算了事件之间的时间。如果时间非常快,那么我假设自动填充(例如 FaceID 或 TouchID)用于输入凭据并自动触发接下来的任何 UI - 在我的例子中,用户点击“登录”。

显然,您必须设置要监视的 UITextFields 的正确委托,但一旦这样做:

var biometricAutofillTime: Date!

func textFieldDidBeginEditing(_ textField: UITextField) {
    if biometricAutofillTime != nil {
        if Date().timeIntervalSince(biometricAutofillTime) < 0.1 {
            // NOTE: Need to hesitate for a very short amount of time,
            //        because, otherwise, the second UITextField (password)
            //        won't yet be populated
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { self.didTapSignin() }
        }
        biometricAutofillTime = nil
    }
    biometricAutofillTime = Date()
}
Run Code Online (Sandbox Code Playgroud)


dun*_*nc4 0

我认为没有更好的解决方案。

我注意到的一件事是,仅当文本字段为空时才会启用自动填充。

因此,如果文本字段从空到长度大于最小密码/用户名,则很可能是自动填充/粘贴。

我用来shouldChangeCharactersIn检测 UITextField 中的更改。我不确定是否存在在调用委托方法之前可以将键盘中的文本批量处理在一起的情况。

  • 这不再是真的了。自动完成确实需要一个空白字段,它会替换任何现有文本。 (4认同)