Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reference from UITableViewCell to parent UITableView?

Is there any way to access the owning UITableView from within a UITableViewCell?

like image 385
Michael Grinich Avatar asked Jul 10 '09 16:07

Michael Grinich


People also ask

Is it possible to add UITableView within a UITableViewCell?

yes it is possible, I added the UITableVIew within the UITableView cell .. :) no need to add tableview cell in xib file - just subclass the UITableviewCell and use the code below, a cell will be created programatically.

What is UITableView in Swift?

A view that presents data using rows in a single column.

What is IndexPath UITableView?

IndexPath contains information about which row in which section the function is asking about. Base on this numbers you are configuring the cell to display the data for given row.

How do I populate UITableView?

There are two main base ways to populate a tableview. The more popular is through Interface Building, using a prototype cell UI object. The other is strictly through code when you don't need a prototype cell from Interface Builder.


2 Answers

Store a weak reference to the tableView in the cell, which you'd set in -tableView:cellForRowAtIndexPath: of your table's dataSource.

This is better than relying on self.superview to always be exactly the tableView is fragile. Who knows how Apple might re-organize the view hierarchy of UITableView in the future.

like image 152
5 revs, 3 users 70% Avatar answered Sep 26 '22 08:09

5 revs, 3 users 70%


Here's a nicer way to do it, which does not rely on any particular UITableView hierarchy. It will work with any future iOS version, provided that UITableView does not change classname altogether. Not only this is extremely unlikely, but if it does happen you will have to retouch your code anyway.

Just import the category below and get your reference with [myCell parentTableView]

@implementation UIView (FindUITableView)  -(UITableView *) parentTableView {     // iterate up the view hierarchy to find the table containing this cell/view     UIView *aView = self.superview;     while(aView != nil) {         if([aView isKindOfClass:[UITableView class]]) {             return (UITableView *)aView;         }         aView = aView.superview;     }     return nil; // this view is not within a tableView }  @end 


// To use it, just import the category and invoke it like so: UITableView *myTable = [myTableCell parentTableView];  // It can also be used from any subview within a cell, from example // if you have a UILabel within your cell, you can also do: UITableView *myTable = [myCellLabel parentTableView];  // NOTE: // If you invoke this on a cell that is not part of a UITableView yet // (i.e., on a cell that you just created with [[MyCell alloc] init]), // then you will obviously get nil in return. You need to invoke this on cells/subviews // that are already part of a UITableView. 


UPDATE
There is some discussion in the comments about whether keeping a weak reference is a better approach. It depends on your circumstances. Traversing the view hierarchy has some small runtime penalty as you are looping until the target UIView is identified. How deep are your views? On the other hand, keeping a reference on every cell has a minimal memory penalty (a weak reference is a pointer after all), and generally adding object relationships where they are not needed is considered a bad OO design practice for many reasons, and should be avoided (see details in the comments below).

More importantly, keeping table references inside cells adds code complexity and can lead to errors, because UITableViewCells are reusable. It is no coincidence that UIKit does not include a cell.parentTable property. If you define your own you must add code to manage it, and if you fail to do so effectively you can introduce memory leaks (i.e., cells live past the lifetime of their table).

Because typically you'll be using the category above when a user interacts with a cell (execute for a single cell), and not when laying-out the table in [tableView:cellForRowAtIndexPath:] (execute for all visible cells), the runtime cost should be insignificant.

like image 36
DTs Avatar answered Sep 23 '22 08:09

DTs