Robin Pain
Robin Pain

Reputation: 639

Objective-C, how to Generally resignFirstResponder?

(my boss says) that I have to implement a "Done" button on a navBar so that the various items in the view (that contain an edit box) will dismiss their keyboard (if they were in focus).

It seems that I must iterate through all items and then call resignFirstResponder on each on the off-chance that one of them is in focus? This seems a bit messy (and hard to maintain if e.g. someone else adds more items in future) - is there a better way to do it?

Upvotes: 6

Views: 9482

Answers (4)

mert
mert

Reputation: 1098

I think best way to handle it by searching all subviews of main view with recursive function, check example below

- (BOOL)findAndResignFirstResponder {
if (self.isFirstResponder) {
    [self resignFirstResponder];
    return YES;
}

    for (UIView *subView in self.subviews) {
        if ([subView findAndResignFirstResponder]) {
            return YES;
        }
    }
    return NO;
}

and also you can put this method to your utility class and can use from tap gesture. All you have to do is simply adding to gesture to view.

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(hideEverything)];
[self.tableView addGestureRecognizer:gestureRecognizer];

and than you can call hideEverything method;

- (void) hideKeyboard {
    [self.view findAndResignFirstResponder];
    ...
    ...
}

Upvotes: 0

Robin Pain
Robin Pain

Reputation: 639

I have found it!

Thanks to this

I discovered that all I need do is this:-

-(void) done {
    [[self.tableView superview] endEditing:YES];
}

// also [self.view endEditing:YES]; works fine

[remark] Also I learn how to do the equivalent of an "eventFilter" to stop UITableViewController from swallowing background touch events by intercepting them before they get there - from the same, wonderful post on that thread - see "DismissableUITableView". [end of remark]

Upvotes: 16

RVN
RVN

Reputation: 4177

One solution is to use a currentTextField Object,

In .h file have an instance variable as

UITextField *currentTextField;

Now in .m file.

Note : Dont forget to set the delegates of all the textField to this class

- (void)textViewDidBeginEditing:(UITextView *)textView
{
   currentTextField = textField;
}

- (void)textViewDidEndEditing:(UITextView *)textView
{
   currentTextField = nil;
}

Now in your button action method

-(IBAction)buttonTap
{
    if([currentTextField isFirstResponder])
        [currentTextField resignFirstResponder];
}

This avoids iterating through all the text field.

Upvotes: 0

Gobra
Gobra

Reputation: 4261

You don't have to iterate through the controls since only one can be first responder at the moment.

This will reset the responder to the Window itself: [[self window] makeFirstResponder:nil]

Upvotes: 0

Related Questions