Hiding the keyboard when UITextField loses focus

2019-07-03 15:16发布

问题:

I've seen some threads about how to dismiss the Keyboard when a UITextField loses focus, but it did not work for me and I don't know how. The "touchesBegan:withEvent:" in the following code, never gets called. Why?

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

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

P.S.: This code has been inserted in the view controller which has a UITableView. The UITextField is in a cell from this table.

So, my opinion is: this method is not being called, cause the touch occurs on the UITableView from my ViewController. So, I think, that to I should have to subclass the UITableView, to use this method as I have seen on other Threads, but it may have a easier way.

Could you please help me? Thanks a lot!

回答1:

Make sure you set the delegate of the UITextField to First Responder in IB. And I just put a custom (invisible) UIButton over the screen and set up an IBAction to hide the keyboard. Ex:

- (IBAction)hideKeyboard {
    [someTextField resignFirstResponder];
}

With that hooked up to a UIButton.



回答2:

Here is my solution, somewhat inspired by several posts in SO: Simply handle the tap gesture in the context of the View, the user is 'obviously' trying to leave the focus of the UITextField.

-(void)handleViewTapGesture:(UITapGestureRecognizer *)gesture
{
    [self endEditing:YES];
}

This is implemented in the ViewController. The handler is added as a gesture recognizer to the appropriate View in the View property's setter:

-(void) setLoginView:(LoginView *)loginView
{
    _loginView = loginView;

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self.loginView action:@selector(handleTapGesture:)];    

    [tapRecognizer setDelegate:self];  // self implements the UIGestureRecognizerDelegate protocol

    [self.loginView addGestureRecognizer:tapRecognizer];    
}

The handler could be defined in the View as well. If you are unfamiliar with handling gestures, see Apple's docs are tons of samples elsewhere.

I should mention that you will need some additional code to make sure other controls get taps, you need a delegate that implements the UIGestureRecognizerDelegate protocol and this method:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{    
    if ([touch.view isKindOfClass:[UIButton class]])    // Customize appropriately.
        return NO; // Don't let the custom gestureRecognizer handle the touch   

    return YES;
}


回答3:

-(void)touchesEnded: (NSSet *)touches withEvent: (UIEvent *)event
 {
    for (UIView* view in self.view.subviews) 
    {
        if ([view isKindOfClass:[UITextField class]])
        [view resignFirstResponder];
    }
}