UITextField inside UITableViewCell: becomeFirstResponder in didSelectRowAtIndexPath

16,558

Solution 1

If you have a custom cell, then you can do something like this:

@implementation CustomCell

#pragma mark - UIResponder

- (BOOL)canBecomeFirstResponder
{
    return YES;
}

- (BOOL)becomeFirstResponder
{
    return [self.textField becomeFirstResponder];
}

@end

Then inside the table view delegate:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    if ([cell canBecomeFirstResponder]) {
        [cell becomeFirstResponder];
    }
}

Solution 2

Give tag for each UITextField and and use Following code:

UITableViewCell* cell = (UITableViewCell*)sender.superview.superview;
UITextField *txtField = (UITextField*)[cell viewWithTag:tag];
[txtField becomeFirstResponder];

In didSelectRowAtIndexPath method.

Its working very good.. :)

Solution 3

I think you should include a tag value on the textfield when creating the cell:

- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
      self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];

      if (self) {
        // Init Textfield
        _textField = [[UITextField alloc] init];
        _textField.backgroundColor = [UIColor clearColor];
        _textField.delegate = self;
        _textField.tag = 999;
        [self addSubview:_textField];
      }

    return self;
}

And on the didSelectRowAtIndexPath method use the tag value to recover the object:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
  UITextField *textField = (UITextField*)[cell viewWithTag:999];


  if (![textField isFirstResponder]){
     [textField becomeFirstResponder];
  }

}

I've including a validation to control if the textfield is already the first responder.

Hope it works as you expect

Solution 4

I believe you need to set you textField's delegate property.

Add textField.delegate = self; to your method, before you call [textField becomeFirstResponder]

Share:
16,558
Sebastian Borggrewe
Author by

Sebastian Borggrewe

Entrepreneur, iOS Ninja and Consultant

Updated on June 04, 2022

Comments

  • Sebastian Borggrewe
    Sebastian Borggrewe almost 2 years

    I am currently trying to get this working. Any help is appreciated.

    I have a custom UITableViewCell that has a UITextField inside. When I select the table cell, I would like to make the UITextField first Responder.
    However [textField becomeFirstResponder]; returns false.

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
      UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
      UITextField *textField;
      for (UIView *view in [cell subviews]) {
        if ([view isMemberOfClass:[UITextField class]]) {
          textField = ((UITextField *)view);
        }
      }
    
      [textField becomeFirstResponder];
    }
    

    As requested, the initialisation of the textfield. This is done in the UITableViewCell subclass:

    - (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
      self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    
      if (self) {
        // Init Textfield
        _textField = [[UITextField alloc] init];
        _textField.backgroundColor = [UIColor clearColor];
        _textField.delegate = self;
        [self addSubview:_textField];
      }
    
    return self;
    }