How to reference UITableViewController from a UITableViewCell class?

I don't think you should do that and probably you're doing something wrong but if you really-really need it then just have a property in your CustomCell class.

weak var viewController : UIViewController

then when you create the cell in cellForRowAtIndexPath set the property

cell.viewController = self

after that you can easily access the view controller from within the cell code:

self.viewController.doSomething()

But again, in my opinion, you should redesign your code. The cell should not care about the controller. It should care only about displaying itself and nothing else


I wouldn't create this kind of dependency between the cell and the view controller - that makes the architecture more intricate and the cell not reusable.

I suggest you to use the delegation pattern, which may sound a little complicated - although you're already using (UITableViewDelegate is a typical example):

  • create a protocol MyCellProtocol with one method didTapCell, accepting a UITableViewCell and/or some custom data you want to pass to the view controller
  • create a public delegate property in your custom cell: weak var cellDelegate: MyCellProtocol?
  • in the didTapXXX handler or didSelectRowAtIndexPath of your cell, call self.cellDelegate?.didTapCell(), passing the expected parameters
  • in your view controller, implement the MyCellProtocol
  • in cellForRowAtIndexPath of your view controller, when creating/dequeuing the cell, set its cellDelegate property to self

At this point, when a tap is done in your cell, the didTapCell method of the view controller is called, and from there you can do whatever you need to achieve.

The key point is: rather than making the cell handle the cell tap/selection, notify the view controller and let it do the job.


extension UIView {
    var parentViewController: UIViewController? {
        var parentResponder: UIResponder? = self
        while parentResponder != nil {
            parentResponder = parentResponder!.next
            if let viewController = parentResponder as? UIViewController {
                return viewController
            }
        }
        return nil
    }
}

Inside your cell

if let myViewController = parentViewController as? MyViewController {
    print(myViewController.title)
}