A UITableViewCell Jeopardy

A unique problem arises when a button is placed in a custom cell and on the button’s tap, the cell has to be modified or some information needs to be saved related to the cell – which necessitates that the table cell needs to be accessed. The worst way of doing this would be to call the buttons’s superview and go up in hierarchy till the cell is reached. This is worst approach because the hierarchy of cells change often as Apple modifies and improves its UITableViewController. The most common and cheapest way of doing it would be to set the button’s tag as the row index, and then on the button’s tap event, get that index from the sender (which is the button itself) and access the cell using

- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath

But this is not the best of approaches.Tags are misused heavily and there might always be the risk that the tag of the button may have been set to be something else just for the sake of some other activity. There are multiple better approaches, one of them I am going to describe in this scope. The basic objective of this approach is to connect the button to the table view cell internally. We will create a delegate for the button’s press event and will implement the same in the view controller. This will have the custom cell as a parameter through which we will be able to access the cell.

Steps:

Step1: Create a delegate to handle the button’s tap in your custom cell’s .h file (CustomCell.h):

@class CustomCell;
@protocol CustomCellDelegate < NSObject >
- (void)customCellDidPressMyButton:( CustomCell *)cell;
@end
@interface CustomCell : UITableViewCell

Step 2: Create a property for the delegate, and set it weak

@property (nonatomic,weak) id < CustomCellDelegate > delegate;

Step 3: In your custom cell’s .m file (CustomCell.m) set the target action for the button and implement the selector to call the delegate method


- (void)awakeFromNib
{

[self.customButton addTarget:self
action:@selector(customButtonPressed)
forControlEvents:UIControlEventTouchUpInside];

}
- (void) customButtonPressed
{

[self.delegate customCellDidPressMyButton:self];

}


Now your custom cell is ready with the button’s delegate method to be implemented by the view controller. Here’s how to implement the same in view controller.

Step 4: Implement the delegate method:


@interface MyViewController ()< UITableViewDelegate,UITableViewDataSource, CustomCellDelegate >

- (void)customCellDidPressMyButton:(BAHPropertySearchResultCell *)cell  {

//the cell is in the parameter. Make change to it as required.

}

Step 5: Connect the table view cell with our newly appointed delegate

 
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{

cell.delegate = self;

}

Step 6:  As it is important to assign the delegate, it is also important to remove the delegate when the tableview is done displaying. It can be done in the following method:


- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{

cell.delegate = nil;

}

Hope this helps!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s