Hiding the Keyboard when losing focus on a UITextView

Simplifying tuzzolotron's answer: Where the following outlet is properly connected in your xib

    IBOutlet UITextView *myTextView;

Use this in the view controller:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    if ([myTextView isFirstResponder] && [touch view] != myTextView) {
        [myTextView resignFirstResponder];
    }
    [super touchesBegan:touches withEvent:event];
}

A tap on the View Controller's View, outside of the Text View, will resign the first responder, closing the keyboard.


Another approach I used a lot when working with UITableViews, Searchbar and keyboard is this, I think you can apply it to text field

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideKeyboard)];
[self.tableView addGestureRecognizer:gestureRecognizer];
gestureRecognizer.cancelsTouchesInView = NO;  // this prevents the gesture recognizers to 'block' touches
[gestureRecognizer release];

And then, here's the simple callback function

- (void)hideKeyboard {
    [myTextField resignFirstResponder];
}

Hope it helps


In my view:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];

    // pass touches up to viewController
    [self.nextResponder touchesBegan:touches withEvent:event];
}

In my viewcontroller:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];
    if (keyboardShown && [touch view] != self.TextView) 
    {
         [self.TextView resignFirstResponder];
    }
    [super touchesBegan:touches withEvent:event];
}

- (void)keyboardWasShown:(NSNotification*)aNotification
{    
        keyboardShown = YES;
}

This is an old post, but I was implementing this solution when i found something a lot simpler (maybe it wasn't available back then).

[self.myTextView endEditing:YES];

I'm using a UITableView, so I put this line on the didSelectRowAtIndexPath: method. So far, so good...


Here is a better solution that does not depend upon an outlet and is going to work with any number of UITextField objects in your controller.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];

    if (![[touch view] isKindOfClass:[UITextField class]]) {
        [self.view endEditing:YES];
    }
    [super touchesBegan:touches withEvent:event];
}