Determine which UITableViewCell contains a specified UIControl
If you have UITextField controls inside of a table view cell, and you are hooked into one of the UITextFieldDelegate methods, then you might need to determine which UITableViewCell contains a specified UIControl inside of a delegate method.
The wrong way
Up until now, I have always taken the shortcut of just walking back to the grandparent of the control by doing something like this:
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { UITableViewCell *cell = (UITableViewCell *)textField.superview.superview; // do something here with the cell return YES; } |
However, when building and running under the iOS 7 SDK, this of course does not work any more.
The right way
After researching this phenomenon a bit more, I found a solution that does not rely on walking the view hierarchy, which by the way kids, is usually never a good idea. Here is a category that I built on top of UIView:
- (UITableViewCell *)findParentCellInTableView:(UITableView *)tableView { UITableViewCell *cell = [self findParentUITableViewCell]; return cell; } - (UITableViewCell *)findParentUITableViewCell { if (self.superview && [self.superview isKindOfClass:[UITableViewCell class]]) { return (UITableViewCell *)self.superview; } return [self.superview findParentUITableViewCell]; } |
As a result, now my delegate call looks like this:
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField { UITableViewCell *cell = [textField findParentCellInTableView:tableView]; // do something here with the cell return YES; } |
Since I built this category off of UIView, it will work with most common items built on top of UIView or UIControl that you would put in a table view cell, such as UILabel, UITextField, UITextView, etc.
BTW, Happy Anniversary to The Beatles, who first visited the United States 50 years ago today.
EDIT: My first attempt to create the findParentCellInTableView method ended in disaster, as I forgot to take into account the fact that table view cells can scroll off the screen and possible get reused. As a result, I created a method that walks up the view chain more intelligently than simply going to the superview’s superview. As always, please let me know if you have any comments.