iOS自动填充功能假设密码之前的字段为用户名

时间:2018-10-25 22:47:43

标签: ios ios11 autofill

自动填充效果非常好,但是在一种情况下,它不是最佳选择,而且我不知道围绕一种可能正确的方法进行的工作。

我有一个带有2个UITextFields的屏幕,第一个是Amount,这是要转移给另一个人的货币值。第二个字段是密码,用户需要重新输入密码才能完成交易。

第一个字段(金额)的内容类型设置为.unspecified,第二个字段(密码)的内容类型设置为.password

当用户点击第二个字段“自动填充”时,会很好地提示您要使用的密码,但是,一旦点击正确的密码,iOS会自动假定第一个字段(金额)为用户名,并用与所选内容相关联的用户名进行填充帐户,覆盖用户先前输入的金额。

是否有一种方法可以强制仅自动填充密码?

2 个答案:

答案 0 :(得分:0)

今天,我以不同的方式面对同样的问题。我的情况是将mobile numberpassword输入项输入登录页面。本机应用仅支持手机号码,而网络应用仅支持email。因此,在执行iOS自动填充功能时,它会使用email字段填充手机号码字段,这是不可接受的。

玩了一段时间的自动填充后,我发现UITextField委托的生命周期在自动填充的情况下有所不同。

点击键盘顶部提供的自动填充功能后,UITextFieldDelegate从头开始工作。 尽管键盘已打开,但从当前开始的委托方法如下(按呼叫顺序)

  1. textField(_:shouldChangeCharactersIn:replacementString:)
  2. textFieldShouldEndEditing(_:)

此代表在不关闭键盘的情况下呼叫并再次出现。这很不寻常。 在这种情况下,返回false中的textField(_:shouldChangeCharactersIn:replacementString:)无效。

因此,从理论上讲,我有机会在mobile field中编辑textFieldShouldEndEditing。为此,我要跟踪自动填充开始之前出现的文本。所以取了两个变量

var previousText: String?
var nextText: String?

每当UITextField开始编辑时,我都会将其保存在previousText中,如下所示:

public func textFieldDidBeginEditing(_ textField: UITextField) {
    previousText = textField.text
}

然后我按照以下说明跟踪textField(_:shouldChangeCharactersIn:replacementString:)内部的变化

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    nextText = self.getCompleteString(original: textField.text, replacingRange: range, withString: string)


    // YOU MAY RETURN `true` OR `false` BASED ON KEYBOARD TYPING, BUT RETURNING `false` IN CASE OF AUTOFILL HAS NO EFFECT. SO I ASSUME, YOU RETURN `true` ALWAYS.
    return true;
}

func getCompleteString(original: String?, replacingRange: NSRange, withString: String) -> String? {
    guard var originalText = original else {
        return nil
    }

    guard let range = Range<String.Index>.init(replacingRange, in: originalText) else {
        return nil
    }

    originalText.replaceSubrange(range, with: withString)

    return originalText
}

现在最有趣的部分是检测自定义要求(在我的情况下是检测可能的有效手机号码,而您的情况是在检测有效金额)

func textFieldDidEndEditing(_ textField: UITextField) {
    if textField == MY_MOBILE_TEXT_FIELD {
       if nextText.IS_POSSIBLE_VALID_MOBILE_NUMBER() { // my function to detect the possible valid mobile number
           textField.text = nextText
       } else {
           textField.text = previousText
       }
    }
}

它对我有用,希望它对你也有用。

答案 1 :(得分:0)

自动填充不考虑文本字段委托方法返回的内容

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool 

因此,可以尝试另一种对我有用的技术, 您可以将金额文本字段的textContentType设置为密码类型,并使用键盘上的工具栏在自动填充建议旁边(因为您将使用数字键盘在金额字段中输入数字,因此您可能已经在使用自定义工具栏。)

amount_text_field.textContentType = .password

这样,iOS将假定它是一个密码文本字段,并且不会填充从其他文本字段应用的用户名或密码。使用工具栏应该可以帮助您在此文本字段上隐藏自动填充建议。