call function in table view controller from table view cell

How do I call a function in a table view controller from a table view cell?

Accepted Reply

I put the followin code in ...


        if self == nil { print("!!!") }
    
        uppderView = self.superview as! UITableView


and the print doesn't execute, and I still get the same error about an unxpected nil found.


Maybe the cell hasn't fully initialized itself yet at that time.


I decided to use the following code in the table view cell class and it worked. The cast in the last line worked without any errors when I run the code.


    override func willMove(toSuperview newSuperview: UIView?) {
       
        upperView = newSuperview
       
        while (upperView != nil && !(upperView! is UITableView)) {
            upperView = upperView!.superview
        }
       
        let tableView = upperView as! UITableView
    }

Replies

Depends what you want to do.


If you call when clicking on the select, put the call to the func in delegate

func tableView(UITableView, didSelectRowAt: IndexPath)


if you call by clicking the accessory button, use

func tableView(UITableView, accessoryButtonTappedForRowWith: IndexPath)


if you respond to a click in a button in a cell, the action is defined as the button action.


So, tell more precisely the context if needed.

I put a picker view in a custom table view cell, and I would like for code to run when the picker view makes a pick. I want the code in the table view cell to call a function in the table view controller that hosts the table view.

your view controller will conform to UIPickerViewDelegate


So you should put the code in the delegate func for the pickerView

func pickerView(UIPickerView, didSelectRow: Int, inComponent: Int)


So, from there you can call properties of your viewController.

The problem is that I don't know that there is a way to get a reference of the table view from the table view cell class.

Why do you need this ?


But, you have several solutions :

- call cell.superview.

In fact, you need to call recursively cell.superview.superview. because there are 2 levels of superview between cell and its tableView in IOS7

        var upperView = cell.superview
        while (upperView != nil && !(upperView! is UITableView)) {
            upperView = upperView!.superview
        }
     // need to test later if upperView is nil
     // if not, it is the tableView you looked for

See here for discussion

h ttps://stackoverflow.com/questions/15711645/how-to-get-uitableview-from-uitableviewcell


- create a global var to hold a reference of the tableView


- include a reference of the tableView in the cell class itself :

var parentTable : UITableView?

that you populate when you create the cell

cell.superview is a nil.

Can you show where in code you test for cell.superview ? How is cell defined ?


If that really does not work, a solution is to include a reference to the tableView in the cell class.

I put code in the table view cell class.


var uppderView: Any?
override func awakeFromNib() {
    uppderView = self.superview as! UITableView
}


The result is an error that says, "fatal error: unexpectedly found nil while unwrapping an Optional value", at line 03 above.


When I use your code...


var upperView: Any?
override func awakeFromNib() {

        while (upperView != nil && !(upperView! is UITableView)) { 
            upperView = upperView!.superview 
        } 
}


and I put a breakpoint at line 04, the breakpoint is never reached. Those two tests I mentioned above tells me that self.superview is nil.

The problem is elsewhere.


I tested in Swift 2 and 3 the following :


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     
        let cell = tableView.dequeueReusableCellWithIdentifier("SignalCell", forIndexPath: indexPath) // I get a cell
          Swift.print("cell.superview",  cell.superview!.superview! as! UITableView)


print does not crash : I get

cell.superview <UITableView: 0x7aa5f400; frame = (0 0; 768 1024); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x7878be10>; layer = <CALayer: 0x78788d00>; contentOffset: {0, -64}; contentSize: {768, 352}>

So, that shows that it is probably the cell that is nil

Add a test in the code to know if cell is nil when you call its superview


    if cell == nil { print("no cell ") }

        var upperView = cell.superview 
        while (upperView != nil && !(upperView! is UITableView)) { 
            upperView = upperView!.superview 
        } 
     // need to test later if upperView is nil 
     // if not, it is the tableView you looked for

I put the followin code in ...


        if self == nil { print("!!!") }
    
        uppderView = self.superview as! UITableView


and the print doesn't execute, and I still get the same error about an unxpected nil found.


Maybe the cell hasn't fully initialized itself yet at that time.


I decided to use the following code in the table view cell class and it worked. The cast in the last line worked without any errors when I run the code.


    override func willMove(toSuperview newSuperview: UIView?) {
       
        upperView = newSuperview
       
        while (upperView != nil && !(upperView! is UITableView)) {
            upperView = upperView!.superview
        }
       
        let tableView = upperView as! UITableView
    }

if self == nil { print("!!!") }


Is this inside the cell class ?

I am not sure what self refers to (is it effectively the cell ?)


Anyway, if that works, that means you've done what was needed. Great.


Don't forget to close this long thread and good luck for continuation.

self would be the cell. The code is in the cell class.