Marcus
Marcus

Reputation: 522

Dismiss keyboard for UITextfield in UITableView cell

I have a UITableView to which i've assigned a UITextField to each cell. I want to be able to accept input from each text field and dismiss the keyboard when the user taps anywhere on the screen other than the keyboard. This is the code I have so far, but I find the keyboard only gets dismissed when im on the last cell in the table.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [self.gradesTableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    self.tf = [[UITextField alloc] initWithFrame:CGRectMake(225, (cell.contentView.bounds.size.height-30)/2, 50, 30)];

    [self.tf setDelegate: self];
    self.tf.tag = indexPath.row;

    self.tf.textAlignment = NSTextAlignmentCenter;
    self.tf.placeholder = @"0";
    self.tf.backgroundColor = [UIColor grayColor];
    self.tf.borderStyle = UITextBorderStyleRoundedRect;
    self.tf.keyboardType = UIKeyboardTypeDecimalPad;

    [cell addSubview:self.tf];

    cell.textLabel.text = [self.adderArrayLabels objectAtIndex:indexPath.section];
    return cell;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField{
    self.tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
    [self.view addGestureRecognizer:self.tapGR];
    NSLog(@"Started editing");
}

Ive tried both endEditing: and resignFirstResponder but both only dismiss the keyboard when im on the textfield in the last cell.

- (void)tap {
    [self.tf endEditing:YES];
    //[self.tf resignFirstResponder];

    NSLog(@"tap called");
    self.tapGR.enabled = NO;
}

With the NSLog statements in the code I can confirm the method tap is called every time the appropriate tap gesture is recognized but still the keyboard stays. How do I fix this?

Upvotes: 1

Views: 2414

Answers (1)

nhgrif
nhgrif

Reputation: 62052

The problem is here:

self.tf

Your class has a text field property, and every time you create a new text field, you assign it to this property. Then, you only try to endEditing: or resignFirstResponder on this property, which will always be the text field on the cell most recently created.

You don't need this property at all and can just use a local text field variable when creating the cells.

Then change your tap method to this:

- (void)tap {
    [self.view endEditing:YES];

    NSLog(@"tap called");
    self.tapGR.enabled = NO;
}

And truly, the method should probably be: - (void)tap:(id)sender;

Also, as I commented, the gesture recognizer should be added in viewDidLoad. We only need to add it once, not each and every time a text field begins editing. The only reason to add it every time a text field begins editing is if you're also removing it every time the text field ends editing... but as the method that the gesture calls simply gets rid of the keyboard, I see no reason to do that.

Upvotes: 1

Related Questions