I've got a text field delegate setup which disables/enables the done button on keyboard when certain conditions are met (between 5 and 15 characters, not just whitespace, etc...) using the "inputDelegate.returnKeyEnabled" key (which is wrapped by ElId.Key.enableDone
). Everything seemed to work fine, except the done button would start off enabled before editing.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text else { return true }
let newLength = text.count + string.count - range.length
let booleanValue = isValidText(text, length: newLength)
self.rightActionButton?.isEnabled = booleanValue
textField.enablesReturnKeyAutomatically = false
textField.setValue(booleanValue,
forKeyPath: ElId.Key.enableDone)
return true
}
func isValidText(_ text: String, length: Int) -> Bool {
return ((length >= minNameLength) && (length <= maxNameLength)) && !text.trimmingCharacters(in: .whitespaces).isEmpty && !text.last!.isWhitespace && !text.first!.isWhitespace
}
At first I tried to set the textfield's "inputDelegate.returnKeyEnabled" false beforehand, but that didn't work.
After reading other answers here, it looked like I could start with the done button by setting enablesReturnKeyAutomatically
to true before editing. And it sort of did; except: The done button enables after I start typing, until I've tapped a certain number of characters and then start deleting. At this point, it starts to work as expected.
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
textField.enablesReturnKeyAutomatically = true
// textField.setValue(false,
// forKeyPath: ElId.Key.enableDone)
return true
}
I've confirmed through breakpoints that enablesReturnKeyAutomatically
is only true at first and then is false after the first keystroke and that the isValidText
method is returning false from the first keystroke; but done button enables as soon as I start typing and then stays enabled until after several keystrokes.
How can I start with a disabled done/return/go button on the keyboard and KEEP it disabled until the validation requirements are met?
UPDATE
Realized that while the length was validating properly, my whitespace checks were still being applied to the previous value not the new one. Thought this might be the culprit and updated my method to correct for this, however now the validation not working at all. isValidText
method still returns false when it should, but done button is always enabled. Maybe this will draw light onto the mistake.
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
guard let text = textField.text,
let textRange = Range(range, in: text) else { return true }
let updatedText = text.replacingCharacters(in: textRange,
with: string)
// let newLength = text.count + string.count - range.length
let booleanValue = isValidText(updatedText)//, length: newLength)
self.rightActionButton?.isEnabled = booleanValue
textField.enablesReturnKeyAutomatically = false
textField.setValue(booleanValue,
forKeyPath: ElId.Key.enableDone)
return true
}
func isValidText(_ text: String/*, length: Int*/) -> Bool {
return ((text.count >= minNameLength) && (text.count <= maxNameLength)) && !text.trimmingCharacters(in: .whitespaces).isEmpty && !text.last!.isWhitespace && !text.first!.isWhitespace
}
When I stop setting enablesReturnKeyAutomatically
to true beforehand, the new version of the method works as expected. The only problem is that the Done button is then enabled from the beginning but immediately disables as text is written.