2

I have a UITableView in my application where I have custom UITableViewCell which contains a UITextField. What I would like to do is get the correct index of the row when I select a particular textfield from that row.

Unfortunately, I am only able to get the correct index of the row if I actually click on the row, and not when I select the textfield itself. I am implementing the <UITextFieldDelegate>, and when I select a particular UITextField, I call the method:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {

    int rowTest = [_table indexPathForSelectedRow].row;
    int rowTest1 = [_cell.tireCodeField tag];
    
    NSLog(@"the current row is: %d", rowTest1);
    NSLog(@"and this row is: %d", rowTest);  

    return YES;
    
}

The problem is that the value for the row that I am getting is from whenever the method:

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

   ...

}

gets called. It is as if there is a disconnect between the UITextField and the row in the table it resides in.

Is there a way for me to get the index of the row by selecting the UITextField that resides within it, instead of selecting the row itself?

halfer
  • 19,824
  • 17
  • 99
  • 186
syedfa
  • 2,801
  • 1
  • 41
  • 74

5 Answers5

8

The way this is usually done, is to give the text field a tag equal to the indexPath.row, or if you have multiple sections, some mathematical combination of the section and row (like 1000*indexPathSection + indexPath.row).

rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • I do that in my cellForRowAtIndexPath method, but as i said, this value only seems to change when I select didSelectRowAtIndexPath. – syedfa Aug 15 '13 at 15:18
  • @syedfa, I don't understand what you mean by "it only changes when I select didSelectRowAtIndexPath". You shouldn't be checking _cell.tireCodeField.tag, just textField.tag – rdelmar Aug 15 '13 at 15:24
  • It turns out that I had to use an offset value when setting the .tag value for the textfield. So in my cellForRowAtIndexPath method, I had to change my code to: cell.textField.tag = indexPath.row+50; and then in my textFieldShouldBeginEditing method, I did this: int row = textField.tag-50; It was only after doing this did it start working! – syedfa Aug 15 '13 at 16:12
  • @syedfa, using int row = textField.tag should have worked by itself. Did you try it that way? Sometimes it is necessary to use an offset, but usually only to avoid conflict with other views with tags. – rdelmar Aug 15 '13 at 16:56
7

Well, assuming that the cell is the direct superview or the text field, you can directly ask for the text field's superview, cast to UITableViewCell, and then ask your instance of UITableView for the index path of that cell. Here's an example:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
    UITableViewCell *cell = (UITableViewCell *)textField.superview; // cell-->textfield
    //UITableViewCell *cell = (UITableViewCell *)textField.superview.superview; // cell-->contentView-->textfield
    NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

    return YES;
}

If you're looking for a more dynamic solution that works across multiple versions of iOS, then you'll probably want to use the following quoted from @Marko Nikolovski here

// Get the cell in which the textfield is embedded
id textFieldSuper = textField;

while (![textFieldSuper isKindOfClass:[UITableViewCell class]]) {
    textFieldSuper = [textFieldSuper superview];
}

// Get that cell's index path
NSIndexPath *indexPath = [self.tableView indexPathForCell:(UITableViewCell *)textFieldSuper];

This method crawls up the superview until it encounters a UITableViewCell. This keeps the code working even when the cell's view hierarchy changes, like it did from iOS 6 to 7.

Community
  • 1
  • 1
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
  • Thanks very much for your response. If I'm using a custom UITableViewCell, do I use that class to call the superview of the textfield, or do I use UITableViewCell as you mentioned above? – syedfa Aug 15 '13 at 15:33
  • 1
    @syedfa Yes, you use your subclass. – Mick MacCallum Aug 15 '13 at 16:11
  • This seems to have stopped working with IOS7. Any ideas? – T.J. Dec 19 '13 at 20:49
  • @T.J. Try `superview.superview`. The view hierarchy of the cell changed in iOS 7, I don't remember the specific changes, but just keep crawling up the superview chain until you hit a `UITableViewCell`. – Mick MacCallum Dec 19 '13 at 20:50
  • 1
    I found a good solution here which crawls up the chain programmatically: http://stackoverflow.com/a/18980944/971518. – T.J. Dec 19 '13 at 20:54
  • @T.J. Perfect. I'll add a link to that in my answer. – Mick MacCallum Dec 19 '13 at 20:57
4

I thought I'd post this slightly (!) late answer as I was trying to do this for ages and then remember another method (which if I say so myself is one of the best ways) of getting the index path for a cell when a UIButton was tapped.

In a similar way you can get the CGPoint of the cell.

-(NSIndexPath *)indexPathForTextField:(UITextField *)textField
{
    CGPoint point = [textField convertPoint:CGPointZero toView:self.tableView];
    return [self.tableView indexPathForRowAtPoint:point];
}

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

I think this is far neater than relying on tags or the even yuckier method of looking at superviews!

Community
  • 1
  • 1
Rich
  • 8,108
  • 5
  • 46
  • 59
1

As it seems you are working with tags,using the UITextFieldDelegate,you can declare this methods in order to select the row.

-(void)textFieldDidBeginEditing:(UITextField *)textField{

int rowTest1 = textField.tag;

[myTableview selectRowAtIndexPath:[NSIndexPath indexPathForRow:rowTest1 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];

}

-(void)textFieldDidEndEditing:(UITextField *)textField{
[textField resignFirstResponder];
}
Pugin
  • 346
  • 1
  • 6
  • 19
-1
UITableViewCell *textFieldCell = (UITableViewCell*) [[[textfield superview]superview]superview];
    NSIndexPath *indexPath = [self.editProfileTableView indexPathForCell:textFieldCell];
CloudyMarble
  • 36,908
  • 70
  • 97
  • 130
AP_
  • 1,013
  • 12
  • 13