There two UITextField (email, password) in the Login/SIgnup controllers in my code (here is the example), so that users obviously could insert login/password to register/log in.
In the method shouldChangeCharactersIn
I check the data inserted by user and afterwards execute method loginButtonChangeState()
, that activates the login button, in case data inserted are correct:
- Email: should be an email, checked with RegEx.
- Password: Should be at least 6 characters in length
Here is the content of the method:
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if let text = textField.text,
let textRange = Range(range, in: text) {
let updatedText = text.replacingCharacters(in: textRange, with: string)
switch textField {
case _ where textField.isIdentical(with: email) : state[textField] = chekMail(for: updatedText)
case _ where textField.isIdentical(with: password) : state[textField] = chekPass(for: updatedText)
default: break
}
loginButtonChangeState()
print("shouldChangeCharactersIn: textField.text:\(text), replacementString: \(string)")
}
return true
}
This code works well, but the following sequence of actions breaks it, and login button keeps active.
- Enter Email , e.g. t@t.com
- Than enter password, e.g. 123456
- Login button – becomes active
- tap/go to the address field again
- tap/go back to the password field
- tap on the keyboard backspace button à login button keeps active though it should have become inactive.
The reason, why it keeps active, is because after taping backspace shouldChangeCharactersIn
method transfers old content of the UITextField
, which can be seen in the console log
shouldChangeCharactersIn: textField.text:, replacementString: t
shouldChangeCharactersIn: textField.text:t, replacementString: @
shouldChangeCharactersIn: textField.text:t@, replacementString: t
shouldChangeCharactersIn: textField.text:t@t, replacementString: .
shouldChangeCharactersIn: textField.text:t@t., replacementString: c
shouldChangeCharactersIn: textField.text:t@t.c, replacementString: o
shouldChangeCharactersIn: textField.text:t@t.co, replacementString: m
shouldChangeCharactersIn: textField.text:, replacementString: 1
shouldChangeCharactersIn: textField.text:1, replacementString: 2
shouldChangeCharactersIn: textField.text:12, replacementString: 3
shouldChangeCharactersIn: textField.text:123, replacementString: 4
shouldChangeCharactersIn: textField.text:1234, replacementString: 5
shouldChangeCharactersIn: textField.text:12345, replacementString: 6
shouldChangeCharactersIn: textField.text:123456, replacementString:
In this row "shouldChangeCharactersIn: textField.text:123456, replacementString: " it is seen, that replacementString
is "space sighn", but textField.text
still contains "123456".
Video can be seen here: https://github.com/AdAvAn/ShouldChangeCharactersInRange/raw/master/shouldChangeCharactersIn.gif
QUESTION:
How can I correct the work of the method so that “Log In” button become inactive after taping backspace on keyboard (Ideally without clearing the content of the password UITextField)?
UDP: 25.03.18
This problem only occurs for fields that have the isSecureTextEntry
parameter true.
So far I have not found a more beautiful solution, except to set password.clearsOnBeginEditing = true
. This allows you to clear the contents of the password field each time it triggers func textFieldDidBeginEditing (_ textField: UITextField)
.