Search code examples
iosuitableviewuitextfieldfirst-responder

change first responders in uitableviewcell textfield


I am developing an app using storyboard. There is a custom class for UITableViewCell (MoneyEntryTableViewCell) which contains UITextField.

Question: I want to move the focus to other text fields, added in other cells, as I press Previous/Next (<>) in my Keyboard.

In .h file

@interface MoneyEntryTableViewCell : UITableViewCell

@property (strong, nonatomic) IBOutlet UILabel *lblMemName;
@property (strong, nonatomic) IBOutlet UITextField *textAmount;
@property (strong, nonatomic) IBOutlet UILabel *lblmemId; // Hidden 

@end

In .m file

@implementation MoneyEntryTableViewCell

@synthesize lblMemName,textAmount;
- (void)awakeFromNib {
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];
}

@end

In Controller, this is my cellForRowAtIndexPath func...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    MoneyEntryTableViewCell *cell = (MoneyEntryTableViewCell *)[tableView dequeueReusableCellWithIdentifier:@"UserAmountCell"];
    if (!cell)
    {
         cell = [[MoneyEntryTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UserAmountCell"] ;
    }
    cell.selectionStyle =UITableViewCellSelectionStyleNone;

    UILabel     *lblname  = (UILabel *)    [cell lblMemName];
    lblname.tag =100;
    lblname.text = [[self.MembersList objectAtIndex:indexPath.row] objectAtIndex:0];

    UILabel     *lblId  = (UILabel *)    [cell lblmemId];
    lblId.tag =101;
    lblId.text = [[self.MembersList objectAtIndex:indexPath.row] objectAtIndex:1];

    UITextField *txtfield = (UITextField *)[cell textAmount];
    txtfield.tag = 200 + indexPath.row;
    txtfield.placeholder = @"0.00";
    txtfield.delegate = self;
    [txtfield addTarget:self  action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
    txtfield.inputAccessoryView = keyboardDoneButtonView;

    return cell;
}

Solution

  • @saif Thanks.

    I post my code here.

    Declare in interface. UITextField *activeField;

    - (void)Previous:(id)sender
    {
        [self switchToNextField:NO];
    }
    
    - (void)Next:(id)sender
    {
        [self switchToNextField:YES];
    }
    

    Do your own logic to disable and enable previous & next, By tag you set in UITextfield

    - (void)textFieldDidBeginEditing:(UITextField *)textField {
    
        activeField = textField;
        [self.PrevButton setEnabled:YES];
        [self.NextButton setEnabled:YES];
        if(textField.tag ==200)
            [self.PrevButton setEnabled:NO];
        else if (textField.tag == 200 + [self.MembersList count] - 1) //self.MembersList table Source.
        {
            [self.NextButton setEnabled:NO];
        }
    }
    
    - (void)textFieldDidEndEditing:(UITextField *)textField
    {
        activeField = nil;
    
    }
    

    Pass next = YES if you want next text field to become active. Pass next = NO if you want previous text field to become active

    - (void)switchToNextField:(BOOL)next
    {
        NSLog(@"%ld",(long)activeField.tag);
        if(next)
        {
            float tag = activeField.tag - 200;
            NSIndexPath *indexPathUserName = [NSIndexPath indexPathForRow:tag + 1 inSection:0];
            UITableViewCell *cell = (UITableViewCell *)[self.tblVwSpltList cellForRowAtIndexPath:indexPathUserName];
            UITextField *nextTextField = (UITextField *)[cell.contentView viewWithTag:activeField.tag + 1];
            [nextTextField becomeFirstResponder];
        }
        else
        {
            float tag = activeField.tag - 200;
            NSIndexPath *indexPathUserName = [NSIndexPath indexPathForRow:tag - 1 inSection:0];
            UITableViewCell *cell = [self.tblVwSpltList cellForRowAtIndexPath:indexPathUserName];
            UITextField *nextTextField = (UITextField *)[cell.contentView viewWithTag:activeField.tag - 1];
            [nextTextField becomeFirstResponder];
        }
    }