How to distinguish textFields of a prototype cell in tableView?

I have a tableView with a prototype cell with a textField. I need to figure out how to do next:

  • when a user press on one of the textFields in tableView - he activate it and types a number
  • editing is done, keyboard hides
  • if user press second time on the same textField again then the number he typed first time should be saved and be editable (like he typed number 2, then activate textField again and can edit like 23)
  • if user pressed on a different textField, I need to run different code (reset to 0).

I can determine indexPath of currently edit textField:

 func textFieldDidChangeSelection(_ textField: UITextField) {

        let tapLocation = textField.convert(textField.bounds.origin, to: tableView)

        guard let pickedCurrencyIndexPath = tableView.indexPathForRow(at: tapLocation) else { return }

I thought about storing the row of picked TextField, then if user clicks on the same TF and it matches the saved one - run one code, if row is changed (i.e. user clicked on anther TF) - run different code.

I tried to create an array which holds pressed TF IndexPath, but it doesn't store the previous textField indexPath, each time I press on textField it prints only the current pressed without what I pressed before.

What can I do there?

Answered by Claude31 in 704950022

What you should do in such situation:

  • set a tag for the textFields (in cellAtRow), equal to indexPath.row (if a single section)
  • To avoid possible conflict with other textFields, you coud set as:
textField.tag = indexPath.row + 1000 // if you gave multiple sections:  indexPath.row + 1000 * indexPath.section  for instance

Then, in textFieldDidChangeSelection, use the tag to get the indexPath back

Accepted Answer

What you should do in such situation:

  • set a tag for the textFields (in cellAtRow), equal to indexPath.row (if a single section)
  • To avoid possible conflict with other textFields, you coud set as:
textField.tag = indexPath.row + 1000 // if you gave multiple sections:  indexPath.row + 1000 * indexPath.section  for instance

Then, in textFieldDidChangeSelection, use the tag to get the indexPath back

Here is how I tried to achieve my needs:

 func textFieldDidChangeSelection(_ textField: UITextField) {
    let tapLocation = textField.convert(textField.bounds.origin, to: tableView)
    guard let pickedCurrencyIndexPath = tableView.indexPathForRow(at: tapLocation) else { return }

    //Append only if array don't have the IndexPath already
    if !indexPathsArray.contains(where: {$0 == pickedCurrencyIndexPath}) {
        indexPathsArray.append(pickedCurrencyIndexPath)
    }
   //I need to compare only 2 last IndexPaths, so delete the most old at position 0 in array
    if indexPathsArray.count > 2 {
        indexPathsArray.remove(at: 0)
    }
    
    for indexPath in indexPathsArray {
        if indexPath.last != indexPath.first {
  //user clicked on a new textfield,clear all so he can type a new number
            numberFromTextField = 0
            textField.placeholder = "0"
            textField.text = ""
        }
    }
    print(indexPathsArray)
}

With this code I almost achieved what I need except when I click on a new textField I can't type anything... GIF: cln.sh/sGNlBE

If you have set tags, that would become:

func textFieldDidChangeSelection(_ textField: UITextField) {
    let rowFromTag = textField.tag - 1000 // If you have defined as textField.tag = indexPath.row + 1000
    // I assume there is only one section, but that would be say to adapt
    let pickedCurrencyIndexPath = IndexPath(row: rowFromTag, section: 0)

Then you should continue with your code.

How to distinguish textFields of a prototype cell in tableView?
 
 
Q