Question

I have an app which has a UITableView that uses custom cells, which I created a new class for, CustomCell. A new cell is created every time a press a certain button, and every cell has a UITextField. I want to know how do I make the UITextField in a cell resign first responder after I tap it. Keep in mind that it is initialised in another class, called CustomCell.

UIViewController code:

- (void)viewDidLoad
{
    [super viewDidLoad];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(dismissKeyboard)];

    [self.view addGestureRecognizer:tap];
}
-(void)dismissKeyboard{

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


    static NSString *CellIdentifier= @"Cell";

    CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    }
    if (indexPath.row%2==0){

        n=1;

        cell.inOut.text = [NSString stringWithFormat:@"Entrada %d:", indexPath.row/2 +1];

        cell.entryTime.text = [NSString stringWithFormat:@"%@", [_entryArray objectAtIndex:(indexPath.row+2)]];


        if (indexPath.row==0){
            cell.delta.text=@"";
        }
        else {
            cell.delta.text = [_timeSinceLastEntryArray objectAtIndex:indexPath.row];
        }
    }
    else{
        cell.inOut.text = [NSString stringWithFormat:@"Saída %d:", (indexPath.row+1)/2];
        cell.entryTime.text = [NSString stringWithFormat:@"%@",[_entryArray objectAtIndex:(indexPath.row+2)]];

        cell.delta.text = [_timeSinceLastEntryArray objectAtIndex:indexPath.row];
        if (whichButton==YES){}
        else{
            }
        n=2;

    }
    if( [indexPath row] % 2)
        [cell setBackgroundColor:[UIColor whiteColor]];
    else
        [cell setBackgroundColor:[UIColor lightGrayColor]];



    return cell;
}

CustomCell.h code:

@interface CustomCell : UITableViewCell 

@property (strong, nonatomic) IBOutlet UITextField *inOut;

@property (strong, nonatomic) IBOutlet UILabel *entryTime;
@property (strong, nonatomic) IBOutlet UILabel *delta;

- (void) dismissInOutKeyboard;

@end

CustomCell.m code:

@implementation CustomCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        _inOut = [[UITextField alloc]init];




        _entryTime = [[UILabel alloc]init];

        _delta = [[UILabel alloc]init];

        [self.contentView addSubview:_entryTime];

        [self.contentView addSubview:_inOut];

        [self.contentView addSubview:_delta];

    }
    return self;
}

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

    // Configure the view for the selected state
}

@synthesize  inOut=_inOut, entryTime=_entryTime, delta=_delta;
- (id)initWithFrame:(CGRect)frame reuseIdentifier:(NSString *)reuseIdentifier {

    if (self = [super initWithFrame:frame reuseIdentifier:reuseIdentifier]) {

        // Initialization code

        _inOut = [[UITextField alloc]init];

        _inOut.textAlignment = UITextAlignmentLeft;


        _entryTime = [[UILabel alloc]init];

        _entryTime.textAlignment = UITextAlignmentLeft;


        _delta = [[UILabel alloc]init];

        _delta.textAlignment = UITextAlignmentLeft;

        [self.contentView addSubview:_entryTime];

        [self.contentView addSubview:_inOut];

        [self.contentView addSubview:_delta];

    }

    return self;

}



@end
Was it helpful?

Solution

Simply call findAndResignFirstResponder for the top-most view you have , i.e. UIViewController.view

Declaration:

@interface UIView (findAndResignFirstResponder)
- (void)findAndResignFirstResponder;
- (UIView *)findFirstResponder;
@end

Definition:

@implementation UIView (findAndResignFirstResponder)
- (void)findAndResignFirstResponder {
    [self.findFirstResponder resignFirstResponder];
}

- (UIView *)findFirstResponder {
    for (UIView *subView in self.subviews) {
        if (subView.isFirstResponder)
            return subView;
        UIView* firstResponder = subView.findFirstResponder;
        if(firstResponder)
            return firstResponder;
    }
    return nil;
}

OTHER TIPS

One crude but working implementation that I have used is to create a new UITextField, set it to be a first responder, and then immediately delete it. A basic method of doing this (within a view) is to do something like this:

UITextField *cell = [UITextField new];
[self addSubview:cell];

[cell becomeFirstResponder];
[cell resignFirstResponder];

[cell removeFromSuperview];
cell = nil;

This creates a new cell, adds it to the view so that it can be selected, has it take the focus of the keyboard away from the currently selected cell, hides the keyboard, and then deletes the new cell.

Edit: If you are going to be setting another textfield to be the first responder afterwards, this code is entirely unnecessary. Then, you'd just have to call becomeFirstResponder on the new textfield, and the keyboard focus will automatically shift.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top