I have a UITableViewController and a Prototype cell with a UITextField. When I change a textField.text in one of the cells I want it to be changed in all other cells which my tableView now have (for example multiply number by 2).
This is the behaviour I want to implement: https://cln.sh/xjw5Od (short video)
Should I trigger a certain textField delegate method or it should be made in another way?
My code for now:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell.numberTextField.delegate = self
}
//Delegate methods
func textFieldDidBeginEditing(_ textField: UITextField) {
textField.text = ""
textField.textColor = UIColor.systemBlue
}
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
textField.text = "0"
textField.textColor = UIColor.black
}
OK, so if I understand, you want to type a value in a cell and have twice this value in all other cells as soon as editing ends.
define a dataSource I receive from FRC in my tableView cell as:
- But you do not define the value.
- Is it the initial value ? because later it will be replaced by 2*value entered elsewhere
The use of dataSource remains the solution.
Just adapt the code like this (maybe you can manage color directly, but that's better to rely on dataSource probably:
in cellForRowAt:
cell.numberTextField.text = String(values[indexPath.row].val)
cell.numberTextField.textColor = values[indexPath.row].color
cell.textField.tag = indexPath.row + 1000 // I offset by 1000, in case you have other textFields here
In delegate func:
func textFieldDidBeginEditing(_ textField: UITextField) {
// You want to clear all textFields. Exact ?
for pos in 0..<values.count {
values[pos] = (newValue, .systemBlue)
}
tableView.reloadData() // When editing begins in any cell textField
}
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
let newValue = Int(textField.text) ?? 0 // the value we typed
// update dataSource as needed
for pos in 0..<values.count {
if pos == textField.tag - 1000 { // Don't do it for textField that just ended editing
values[pos] = (newValue, .black) // Keep typed value for the one that has been edited
} else { // To all others, multiply by 2
let doubleValue = newValue * 2
values[pos] = (doubleValue, .black)
}
tableView.reloadData()
}
Calculation should be displayed in a real time
To do so, implement code in another delegate func:
func textFieldDidChangeSelection(_ textField: UITextField) {
let fieldBeingEditedIndex = textField.tag - 1000 // tag of textField being edited, minus offset to get pos for dataSource
let newValue = Int(textField.text) ?? 0 // the value we are typing
// update dataSource as needed
for pos in 0..<values.count {
if pos == fieldBeingEditedIndex { // Don't do it for textField that is being edited
values[pos] = (newValue, .black) // Keep typed value for the one being edited - other color?
} else { // To all others, multiply by 2
let doubleValue = newValue * 2
values[pos] = (doubleValue, .black)
}
var allOtherIndexPath = [IndexPath]() // All, except the one being edited
for i in 0..<values.count where i != fieldBeingEditedIndex {
allOtherIndexPath.append(IndexPath(row: i, section: 0))
}
// reload other cells only, to avoid flicker or other side effects
tableView.reloadData(at indexPaths: allOtherIndexPath, with animation: .none)
}
instead of in
func textFieldDidEndEditing(_ textField: UITextField, reason: UITextField.DidEndEditingReason) {
Is it what you are looking for ?
If not, please explain in a simple use case what you want :
- what are the initial values in cells (from FRC ?)
- You type something in a cell
- What do you then get in all cells ?