У меня есть контроллер представления под названием LoginViewController
, который соответствует UITextFieldDelegate
и имеет два объекта текстового поля, а именно Email
и Password
. На текстовое поле Email
наложена функция проверки электронной почты, и если проверка не пройдена, сработает экземпляр UIAlertController
.
Вот скриншоты сцен и кода, прежде чем я продолжу свой вопрос:
ps: существует множество операторов печати, позволяющих мне понять ход выполнения
func textFieldShouldEndEditing(textField: UITextField) -> Bool {
guard self.validateEmail(self.emailTextField.text!) else {
print("self.presentedViewController: \(self.presentedViewController)")
if self.presentedViewController == nil {
let alertController = UIAlertController(title: "Invalid Email Address", message: "Please try again.", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
print("textFieldShouldEndEditing returnin false: \(textField.placeholder!) text field w/ value: \(textField.text!)")
return false
}
print("textFieldShouldEndEditing returning true: \(textField.placeholder!) text field w/ value: \(textField.text!)")
return true
}
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
print("textFieldShouldBeginEditing: \(textField.placeholder!) text view")
return true
}
func textFieldDidEndEditing(textField: UITextField) {
print("textFieldDidEndEditing: \(textField.placeholder!) text field with value: \(textField.text!)")
}
func textFieldDidBeginEditing(textField: UITextField) {
print("textFieldDidBeginEditing: \(textField.placeholder!) text field")
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
if !(self.emailTextField.text?.isEmpty)! && !(self.passwordTextField.text?.isEmpty)! {
self.emailTextField.resignFirstResponder()
self.passwordTextField.resignFirstResponder()
}
else if !(self.emailTextField.text?.isEmpty)! {
self.passwordTextField.becomeFirstResponder()
}
print("textFieldShouldReturn: \(textField.placeholder!) text field w/ value: \(textField.text!)")
return true
}
Когда правильно отформатированный адрес электронной почты вводится в текстовое поле Email
и фокус перемещается в следующее текстовое поле (Password
) либо с помощью следующей клавиши, либо вручную нажав на следующее текстовое поле (Password
), следующие цепочки методов делегата происходят, как и ожидалось. (и понял):
console output:
Формат: [имя метода делегата: значение заполнителя текстового поля (+ текстовое значение)]
textFieldShouldBeginEditing: Email text field
textFieldDidBeginEditing: Email text field
textFieldShouldBeginEditing: Password text field
textFieldShouldEndEditing returning true: Email text field w/ value: [email protected]
textFieldDidEndEditing: Email text field w/ value: [email protected]
textFieldDidBeginEditing: Password text field
email field is filled
textFieldShouldReturn: Email text field w/ value: [email protected]
Проблема возникает, когда в текстовом поле Email
обнаруживается неправильный отформатированный адрес электронной почты. Метод UITextFieldDelegate
textFieldShouldEndEditing
вызывается три раза вместо одного, поскольку представлен экземпляр UIAlertController
.
ps: предупреждение отображается только один раз на экране.
console output:
Формат: [имя метода делегата: значение заполнителя текстового поля (+ текстовое значение)]
textFieldShouldBeginEditing: Email text field
textFieldDidBeginEditing: Email text field
textFieldShouldBeginEditing: Password text field
//1st occurence
self.presentedViewController: nil
textFieldShouldEndEditing returnin false: Email text field w/ value: bob
//2nd occurence
self.presentedViewController: Optional(<UIAlertController: 0x7f9018662df0>)
textFieldShouldEndEditing returnin false: Email text field w/ value: bob
//3rd occurence
self.presentedViewController: Optional(<UIAlertController: 0x7f9018662df0>)
textFieldShouldEndEditing returnin false: Email text field w/ value: bob
Основываясь на объяснении из этого потока: "textFieldShouldEndEditing вызывается несколько раз", я понимаю, что фокус вот-вот покинет текстовое поле Email
(первое появление метода textFieldShouldEndEditing
срабатывает), фокус уже находится на текстовом поле Password
, таким образом, получая статус первого респондента. Но, поскольку обнаружена недопустимая электронная почта, отображается контроллер предупреждений, и текстовое поле Password
внезапно теряет фокус и, таким образом, также вызывает textFieldShouldEndEditing
. Итак, я ожидаю, что textFieldShouldEndEditing
сработает только дважды (один из-за текстового поля Email
. Другой из-за текстового поля Password
) вместо трех раз (все из-за Email
текстового поля) следующим образом:
textFieldShouldBeginEditing: Email text field
textFieldDidBeginEditing: Email text field
textFieldShouldBeginEditing: Password text field
self.presentedViewController: nil
textFieldShouldEndEditing returnin false: Email text field w/ value: bob
self.presentedViewController: Optional(<UIAlertController: 0x7f9018662df0>)
textFieldShouldEndEditing returnin false: Password text field w/ value: nil
Но это не так. Может ли кто-нибудь просветить, почему мое понимание неверно. Спасибо за любой указанный указатель.