Here's my code below. The textfield is outside of the table view. I do use reloadRows. I call it from textField(:charactersShouldChangeIn::). It reloads the row so that the table view cell in the row shows the current state of text field's text property before the text property is updated with the change the user made.
self.temporaryMessageBeingEdited?.subject is type String, as you must realize. This temporaryMessageBeingEdited object is in the array the table view uses at the same chronological position as the table view row that is reloaded as must be obvious to you.
Neither the textDidChange(:) nor the textWillChange(:) ever fires, though the other two callback methods of the UITextInputDelegate do fire when I test the code by typing into the text field during run time.
// MARK: - UITextFieldDelegate
extension MessagesViewController: UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
print("#", #function)
guard string != "\n" else {
return false
}
self.temporaryMessageBeingEdited?.subject = self.textFieldSubject.text
if let guardedIndexPathToReload = self.indexPathOfMessageBeingEdited {
self.tableView.reloadRows(at: [guardedIndexPathToReload], with: .none)
}
return true
}
}
// MARK: - UITextInputDelegate
extension MessagesViewController: UITextInputDelegate {
func selectionWillChange(_ textInput: UITextInput?) {
print("#", #function)
}
func selectionDidChange(_ textInput: UITextInput?) {
print("#", #function)
}
func textWillChange(_ textInput: UITextInput?) {
print("#", #function)
}
func textDidChange(_ textInput: UITextInput?) {
print("#", #function)
}
}
}
}