Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a UITableViewCell from one of its subviews

I have a UITableView with a UITextField in each of the UITableViewCells. I have a method in my ViewController which handles the "Did End On Exit" event for the text field of each cell and what I want to be able to do is update my model data with the new text.

What I currently have is:

- (IBAction)itemFinishedEditing:(id)sender {
    [sender resignFirstResponder];

    UITextField *field = sender;
    UITableViewCell *cell = (UITableViewCell *) field.superview.superview.superview;

    NSIndexPath *indexPath = [_tableView indexPathForCell:cell];

    _list.items[indexPath.row] = field.text;
}

Of course doing field.superview.superview.superview works but it just seems so hacky. Is there a more elegant way? If I set the tag of the UITextField to the indexPath.row of the cell its in in cellForRowAtIndexPath will that tag always be correct even after inserting and deleting rows?

For those paying close attention you might think that I have one .superview too many in there, and for iOS6, you'd be right. However, in iOS7 there's an extra view (NDA prevents me form elaborating) in the hierarchy between the cell's content view and the cell itself. This precisely illustrates why doing the superview thing is a bit hacky, as it depends on knowing how UITableViewCell is implemented, and can break with updates to the OS.

like image 648
mluisbrown Avatar asked Jul 20 '13 01:07

mluisbrown


1 Answers

Since your goal is really to get the index path for the text field, you could do this:

- (IBAction)itemFinishedEditing:(UITextField *)field {
    [field resignFirstResponder];

    CGPoint pointInTable = [field convertPoint:field.bounds.origin toView:_tableView];    

    NSIndexPath *indexPath = [_tableView indexPathForRowAtPoint:pointInTable];

    _list.items[indexPath.row] = field.text;
}
like image 65
rmaddy Avatar answered Sep 22 '22 20:09

rmaddy