0

I am working in swift. I have a textfield that is in a tableview cell. I am trying to store the text of each text field in the tableview so they when the user adds or deletes a row, and then the tableview reloads data, that the text fields stay filled in with the appropriate data.

I tried adding a textfielddidendeditting function but for some reason it is not being called.

EDIT:

Here is my code:

tableViewController:

import UIKit

var rowCount = 0
var textArray = [String]()

class TableViewController: UITableViewController {


override func viewDidLoad() {
    super.viewDidLoad()
}


override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return rowCount
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell

    return cell
}

@IBAction func addRow(_ sender: Any) {
    rowCount = rowCount + 1
    textArray.append("")
    tableView.reloadData()
}

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        rowCount = rowCount - 1
        textArray.remove(at: indexPath.row)
        tableView.deleteRows(at: [indexPath], with: .fade)

    } else if editingStyle == .insert {
    }
}


}

tableViewCell:

import UIKit

class TableViewCell: UITableViewCell, UITextFieldDelegate {


@IBOutlet weak var textField: UITextField!

override func awakeFromNib() {
    super.awakeFromNib()
    textField.delegate = self

}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}

func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
    if let myIndexPath = tableView.indexPathForSelectedRow {
        let newText = textField.text
        textArray.insert(newText, at: myIndexPath)
    }

    return true
}

}
2
  • 4
    "I tried adding a textfielddidendeditting function but for some reason it is not being called" But unless you show us your code, we cannot tell you what that reason is. Commented Jan 7, 2019 at 21:09
  • 2
    Also, this is a very common need (communicate text from textfield in table view cell into table view's model data). Did you try searching before asking? Commented Jan 7, 2019 at 21:10

1 Answer 1

3

As far as I could suggest (without any code insight given) you could do the following:

  1. Use a callback in your cell, which gets called every time the textfield ends editing:

.

class MyTableViewCell: UITableViewCell {
       var textHasChanged: ((String) -> Void)?
       ...
    } 
    extension MyTableViewCell: UITextFieldDelegate {
    // this gets called every time the user ends editing the text field
    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
            let newValue = textField.text //here you have your value

            // now save it to your data source
            self.textHasChanged(newValue)
        }
    }
  1. In a initializer or in awakeFromNib() function (depends on your usage), set the .delegate property of the textfield to self

  2. Now, to have each cell display the value from the datasource and to apply the changed text to your tableView datasource, add the following lines to your UITableViewController:

.

class MyTableViewController: UITableViewController {
    var textArray: [String] = ["abc", "def"]
    ...
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)

        cell.textField.text = textArray[indexPath.row]
        cell.textHasChanged = { (newValue) in
            self.textArray[indexPath.row] = newValue
        }
        return cell
}

Just comment if you have further questions

Sign up to request clarification or add additional context in comments.

3 Comments

Hey Muli. Thanks for the advice. My first mistake was I forgot to set the .delegate to self. Now that I have fixed that simple mistake I would like to set the new textfield text to a specific index in an array which is the same as the row that the textfield is in. The problem here is I do not know how to get the indexPath.row of the current row when inside the tableViewCell. Therefore I am getting and error when I define myIndexPath. Any tips?
see updated answer. The mistake you're making is trying to access the tableView and its datasource from your cell. You have to use another delegate or a callback like I did. Add the callback from step 1 to you UITableViewCellFeel, call the function in your textFieldShouldEdit and apply step 3 to your TableViewController. Feel free for further questions.
@Ilya what the status concerning your question? Did you solve it? Do you need further help?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.