Сегодня я столкнулся с той же проблемой, но по-другому.Моя ситуация заключается в вводе mobile number
и password
записи на странице входа.Собственное приложение поддерживает только номер мобильного телефона, а веб-приложение поддерживает только email
.Поэтому, пока работает автозаполнение iOS, оно заполняет поле мобильного номера полем email
, что недопустимо.
После некоторой игры с автозаполнением я обнаружил жизненный цикл UITextField
делегат несколько отличается в случае автозаполнения.
При нажатии автозаполнения, расположенного в верхней части клавиатуры, UITextFieldDelegate
начинает работать с самого начала. Несмотря на то, что клавиатура открыта, метод делегата запускается с текущего с порядком вызова следующим образом
textField(_:shouldChangeCharactersIn:replacementString:)
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
}
}
}
Это сработало для меня, надеюсь, это сработает и для вас.