Reputation: 13
In my swift project I have a tableViewController, with class TableViewController, and one prototype cell, with class TableViewCell. Now I want to use: tableView.reloadData(), or other function, in the class TableViewCell. I put a button into the prototype cell, here the code:
class TableViewCell: UITableViewCell {
let tableViewController = TableViewController()
@IBAction func actionButton(_ sender: UIButton) {
tableViewController.tableView.reloadData() // or other function
}
}
by this method the result is: unexpectedly found nil while unwrapping an optional value. I checked that the class TableViewController is loaded before than the class TableViewCell, so I don't found the problem. Can you help me to find how this error occur?
Upvotes: 1
Views: 34
Reputation: 53231
Your actionButton
method is creating a new instance of TableViewController
each time it's called. It does not refer to the TableViewController
which (presumably) is presenting the cells.
You can handle this in a few of ways. A delegate
protocol is the "classic" way to do this, or you could use a Swift closure.
Delegate method
In your cell
protocol TableViewCellDelegate: class {
func tableViewCellDidTapButton(_ tableViewCell: TableViewCell)
}
class TableViewCell: UITableViewCell {
var weak delegate: TableViewCellDelegate?
@IBAction func actionButton(_ sender: UIButton) {
delegate?.tableViewCellDidTapButton(self)
}
}
In your view controller
class TableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
cell.delegate = self
return cell
}
}
extension class TableViewController: TableViewCellDelegate {
func tableViewCellDidTapButton(_ tableViewCell: TableViewCell) {
let indexPath = indexPath(for: tableViewCell)
// do something
}
}
Closure method
In your cell
class TableViewCell: UITableViewCell {
var didTapButton: Void -> () = { }
@IBAction func actionButton(_ sender: UIButton) {
didTapButton()
}
}
In your view controller
class TableViewController: UITableViewController {
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = dequeueReusableCell(withIdentifier: "TableViewCell", for: indexPath) as! TableViewCell
cell.didTapButton = {
// do something with this indexPath
}
return cell
}
}
Upvotes: 1
Reputation: 733
you can't call TableViewController from other class
you need to use NotificationCenter or protocol
Upvotes: 0