martin
martin

Reputation: 1007

iOS How to select row, when a person selects the UITextField inside it?

So I have a UITableView, where all cells have a UITextField in them as a subview with a tag=1. What's troubling me is that I want when a user clicks on a textField and edits it to know on which row has that happened. What I think can solve it, is to make the cell select itself when the subview (UITextField) is selected. How can I achieve that?

I tried with an array, but because cells are reused, it wouldn't work. Looping through all of the rows would be simply too slow.

Upvotes: 2

Views: 1355

Answers (6)

yoyoyoooooo
yoyoyoooooo

Reputation: 11

Disable the UITextField in each of your cells by default and use your UITableView delegate method didSelectRowAtIndexPath: to

  1. Store the indexPath of the selected row in a property
  2. Enable the UITextField
  3. Make the UITextField first responder

Define the property in your class extension:

@interface MyTableViewController ()
@property (strong, nonatomic) NSIndexPath *activeIndex;
@end

In your implementation of didSelectRowAtIndexPath::

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{
    self.activeIndex = indexPath;
    AddCell *selectedCell = (AddCell *)[self.tableView cellForRowAtIndexPath:indexPath];
    [selectedCell.textField setEnabled:YES];
    [selectedCell.textField becomeFirstResponder];
}

You'll want to disable the UITextField again when it resigns its first responder status.

Assuming your UITableViewController is the delegate for each UITextField, you can do this in your implementation of the UITextFieldDelegate method:

-(void)textFieldDidEndEditing:(UITextField *)textField 
{
    [textField setEnabled:NO];
}

Upvotes: 2

Matthias Bauch
Matthias Bauch

Reputation: 90117

The correct approach is to convert the textFields bounds so it is relative to the tableView, and then use the origin of this rect to get the indexPath.

CGRect rect = [self.tableView convertRect:textField.bounds fromView:textField];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rect.origin];
[self.tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];

Upvotes: 1

Priyanka
Priyanka

Reputation: 152

Code below will return NSIndexPath.This can be written in UITextField delegate -

[tableView indexPathForRowAtPoint:textField.superview.superview.frame.origin];

Try above line your code.

Upvotes: 0

Guillaume Algis
Guillaume Algis

Reputation: 11006

Use the UITextFieldDelegate to know when the user start editing a UITextField (with textFieldDidBeginEditing:).

Two solutions then:

Solution 1: Subclass your cell and make it the delegate of the UITextField.

Then in textFieldDidBeginEditing: of your custom cell, make the cell selected:

// MyCustomCell.m
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self setSelected:YES animated:YES];
}

Solution 2: Make the view controller the UITextField delegate, and select the right cell from there.

// MyTableViewController.m
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    // Find the cell containing our UITextField
    UIView *cell = textField.superview;
    while (![cell isKindOfClass:[UITableViewCell class]])
    {
        cell = cell.superview;
    }

    // Make the cell selected
    [(UITableViewCell *)cell setSelected:YES animated:YES];
}

I'd recommend the first solution, as Andrey Chevozerov said in the comments of one of the answers:

It's better to not use superview for such tasks. Especially in cascade.

Upvotes: 0

Andrei Chevozerov
Andrei Chevozerov

Reputation: 1029

Why you're using tags for textfields? The proper way is:

  1. create custom class for cell;
  2. make an outlet for your UITextField;
  3. when creating cells assign your view controller as a delegate for the cell's text field;
  4. assign a tag == indexPath.row to the corresponding cell's text field;
  5. in textFieldShouldBeginEditing place a code for selecting cell:

    [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:textfield.tag inSection:0] animated:YES scrollPosition:UITableViewScrollPositionNone];

Upvotes: -2

Lithu T.V
Lithu T.V

Reputation: 20021

textfield.superview.superview gives you the cell instance. Use the delegate to get the action

Upvotes: 1

Related Questions