Search code examples
swiftuitableviewcustom-cell

How to reference custom UITableView cell inside another function (Swift)


I am trying to achieve functionality similar to Apple's reminders app where a tableview holds all the reminders and a + button at the end adds a new object.

My objects are held in an array called tempActions, which is the data source for the tableView.

Pressing 'Add Action' appends a new object to the array with the title "Empty Cell".enter image description here

The title is a UITextView which users will be able to edit, but here's what I can't figure out how to do:

How do I take the text from the UITextView of that particular cell, append it to the array at the correct index (the index corresponds to indexPath.row) and then display it in the cell.label?

I thought of using the textViewDidEndEditing method but what I don't know how to do is reference the correct cell from the cellForRowAt method.

Would anyone be able to help clarify this, or am I approaching it in the wrong way?

Here's the code for the entire class:

class Step3: UIViewController, UITableViewDelegate, UITableViewDataSource, UITextViewDelegate {

// Outlets
@IBOutlet weak var sectionText: UILabel!
@IBOutlet weak var sectionHeader: UILabel!
@IBOutlet weak var teableViewHeight: NSLayoutConstraint!
@IBOutlet weak var tableview: UITableView!

@IBAction func addAction(_ sender: Any) {

    tempActions.append(Action(title: "Empty Cell", completed: false))

    tableview.reloadData()
    tableview.layoutIfNeeded()
    teableViewHeight.constant = tableview.contentSize.height

    print(tempActions)
}

@IBAction func nextAction(_ sender: Any) {

    let newGoal = Goal(
        title: tempTitle,
        description: tempDescription,
        duration: tempDuration,
        actions: nil,
        completed: false
    )

    newGoal.save()

    performSegue(withIdentifier: "ToHome", sender: nil)
}


func textViewDidEndEditing(_ textView: UITextView) {
}


func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tempActions.count
}

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

    cell.label.text = tempActions[indexPath.row].title
    cell.label.textContainerInset = UIEdgeInsets(top: 12, left: 0, bottom: 12, right: 0);
    cell.label.delegate = self

    return cell
}

override func viewDidLoad() {
    super.viewDidLoad()
    tableview.estimatedRowHeight = 40
    tableview.rowHeight = UITableView.automaticDimension
}

}

Thanks in advance


Solution

  • If I understand it -- the textView is in a cell, and you want to find that cell in textViewDidEndEditing. If the superview of the textfield is the cell, you could do this:

    func textViewDidEndEditing(_ textView: UITextView) {
        if let cell = textView.superview as? ActionCell, 
             let indexPath = tableView.indexPath(for: cell) {
          // Now you have the indexPath of the cell
          // update tempActions
    
               // YOUR CODE HERE
    
          // Then reloadRows
          tableView.reloadRows(at: [indexPath]), with: .automatic)
        }
    }
    

    Another thing you could do is make tempAction's type have a unique ID and then store that in the ActionCell -- when you want to find the index, look up the ID in the tempActions array to find its index.