I have a UITableView
with 5 UITableViewCells
. Each cell contains a UIButton
which is set up as follows:
- (UITableView
This problem has two parts:
1) Getting the index path of UITableViewCell
which contains pressed UIButton
There are some suggestions like:
Updating UIButton
's tag
in cellForRowAtIndexPath:
method using index path's row
value. This is not an good solution as it requires updating tag
continuously and it does not work with table views with more than one section.
Adding an NSIndexPath
property to custom cell and updating it instead of UIButton
's tag
in cellForRowAtIndexPath:
method. This solves multiple section problem but still not good as it requires updating always.
Keeping a weak refence to parent UITableView
in the custom cell while creating it and using indexPathForCell:
method to get the index path. Seems a little bit better, no need to update anything in cellForRowAtIndexPath:
method, but still requires setting a weak reference when the custom cell is created.
Using cell's superView
property to get a reference to parent UITableView
. No need to add any properties to the custom cell, and no need to set/update anything on creation/later. But cell's superView
depends on iOS implementation details. So it can not be used directly.
But this can be achieved using a simple loop, as we are sure the cell in question has to be in a UITableView:
UIView* view = self;
while (view && ![view isKindOfClass:UITableView.class])
view = view.superview;
UITableView* parentTableView = (UITableView*)view;
So, these suggestions can be combined into a simple and safe custom cell method for getting the index path:
- (NSIndexPath *)indexPath
{
UIView* view = self;
while (view && ![view isKindOfClass:UITableView.class])
view = view.superview;
return [(UITableView*)view indexPathForCell:self];
}
From now on, this method can be used to detect which UIButton
is pressed.
2) Informing other parties about button press event
After internally knowing which UIButton
is pressed in which custom cell with exact index path, this information needs to be sent to other parties (most probably the view controller handling the UITableView
). So, this button click event can be handled in a similar abstraction and logic level to didSelectRowAtIndexPath:
method of UITableView delegate.
Two approaches can be used for this:
a) Delegation: custom cell can have a delegate
property and can define a protocol. When button is pressed it just performs it's delegate methods on it's delegate
property. But this delegate
property needs to be set for each custom cell when they are created. As an alternative, custom cell can choose to perform its delegate methods on it's parent table view's delegate
too.
b) Notification Center: custom cells can define a custom notification name and post this notification with the index path and parent table view information provided in userInfo
object. No need to set anything for each cell, just adding an observer for the custom cell's notification is enough.