1

I have a custom UITableViewCell with a UITextField in it. When running the app using the iOS 7 target and clicking on the UITextField in a cell, the didSelectRowAtIndexPath does fire, but indexPath is nil. When i run this same code in the iOS 6.1 simulator, indexPath is not nil.

My first question is "why did this change?"

My second question is "what's the best way to get the active indexPath row" since i can't get it using didSelectRowAtIndexPath anymore?

This code below works, but it feels hack-ish.

-(UITableViewCell *) cellFromEdit: (UITextField *) field {
    UIView *view = field.superview;
    while (view) {
        if ([view isKindOfClass:[UITableViewCell class]])
            return (UITableViewCell *) view;
        view = view.superview;
    }
    return nil;
}

- (void)textFieldDidChange:(UITextField *)theTextField {
    UITableViewCell *cell = [self cellFromEdit:theTextField];
    if (!cell)
        return;
    int row = [tableView indexPathForCell:cell].row;
Sam
  • 2,579
  • 17
  • 27
  • Have a look at http://stackoverflow.com/questions/4030811/get-selected-index-of-uitableview – Flexicoder Apr 30 '14 at 19:10
  • I don't see this. I have a table view with cells that contain text fields. The text field does not cover the entire cell. If I tap just in the text field, the `didSelectRowAtIndexPath:` isn't even called. If I do tap on the cell, outside the text field, it is called and it has the proper index path. – rmaddy Apr 30 '14 at 19:12
  • I remember seeing such an error on iOS 7 beta but it got fixed in a later beta version. I suppose it is a problem in your code. Without seeing your original code, we can't advice about the correct solution. Also make sure the text field is in the content view of the cell, otherwise many funny things can happen. – Sulthan Apr 30 '14 at 19:20

1 Answers1

0

Using a similar method as this, you can get the index path of a UITextField in a cell as so:

-(NSIndexPath *)indexPathForTextField:(UITextField *)textField
{
    CGPoint textFieldMiddle = CGPointMake(CGRectGetMidX(textField.bounds), CGRectGetMidY(textField.bounds));
    CGPoint point = [textField convertPoint:textFieldMiddle toView:self.tableView];
    return [self.tableView indexPathForRowAtPoint:point];
}

-(void)textFieldDidChange:(UITextField *)textField
{
    NSIndexPath *indexPath = [self indexPathForTextField:textField];
    // Now you can update the object at indexPath for your model!
}

This is neater than relying on tags or looking at superviews!

To answer the "Why did this change?" question...

iOS 7 UITableViewCell hierarchy is different as it now contains scroll views or something inside the cell to handle the swipe to delete.

Here's a dump of the view hierarchy in iOS 7:

<CustomTableViewCell: 0x8cbc9e0; baseClass = UITableViewCell; frame = (0 0; 320 44); autoresize = W; layer = <CALayer: 0x8cbcc50>>
   | <UITableViewCellScrollView: 0x8c6ceb0; frame = (0 0; 320 44); autoresize = W+H; gestureRecognizers = <NSArray: 0x8c6d0c0>; layer = <CALayer: 0x8cbce50>; contentOffset: {0, 0}>
   |    | <UITableViewCellContentView: 0x8cb54e0; frame = (0 0; 320 44); gestureRecognizers = <NSArray: 0x8cbb990>; layer = <CALayer: 0x8cbb7f0>>
   |    |    | <UILabel: 0x8cbbaf0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x8cbd000>>
   |    |    | <UITableViewLabel: 0x8cbd210; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x8cbd360>>
   |    | <_UITableViewCellSeparatorView: 0x8cc2a10; frame = (15 43.5; 305 0.5); layer = <CALayer: 0x8cc26e0>>
Community
  • 1
  • 1
Rich
  • 8,108
  • 5
  • 46
  • 59
  • One suggestion. Change `CGPointZero` to `CGPointMake(5,5)` or similar. If the top of the text field is at the top of the cell, you may get the wrong cell from this. – rmaddy Apr 30 '14 at 19:20
  • 1
    I'm pretty sure it won't (and I've just tried this out now and used this method before in various places). If you wanted to be sure a better solution would `CGPointMake(CGRectGetMidX(textField.bounds), CGRectGetMidY(textField.bounds))` instead of some random numbers. If you outset the text field, ie `Y=-5` then it would be an issue, but as you have purposely set it up like that you would know about that. – Rich Apr 30 '14 at 19:32