简体   繁体   中英

Dismiss keyboard of UISearchBar with gesture recogniser after returning from modal views

I have implemented a UISearchBar into my application. I have created it programatically and am using it in a view controller (not a tableview). It works perfectly fine, but the problem i am having is using a gesture recogniser to dismiss the keyboard. I want the keyboard to be dismissed when the user taps the screen outside of the keyboard.

I know there are a lot of solutions out there to solve this problem, but i have a rather unique problem that i can't figure out at the moment. I have used the following code to implement this.

I placed this line inside the viewDidLoad method of my ViewController:

    [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:search action:@selector(resignFirstResponder)]];

This method works fine normally, however my view controller presents views modally, so it has the following structure:

ViewController - modally -> view2 -modally -> view3

When view 2 and 3 are dismissed and i get back to the ViewController, the gesture recogniser no longer works. I have the same problem when trying another solution i found:

UIGestureRecognizer* cancelGesture;

- (void) backgroundTouched:(id)sender {
    [self.view endEditing:YES];
}

#pragma mark - UISearchBarDelegate

-(void)searchBarTextDidBeginEditing:(UISearchBar *)search {
    cancelGesture = [UITapGestureRecognizer new];
    [cancelGesture addTarget:self action:@selector(backgroundTouched:)];
    [self.view addGestureRecognizer:cancelGesture];
}

-(void)searchBarTextDidEndEditing:(UISearchBar *)search {
    if (cancelGesture) {
        [self.view removeGestureRecognizer:cancelGesture];
    }
}

I added these into my main ViewController and again it worked fine to start with, but after returning from the modal views the gesture no longer worked.

Any help would be appreciated please!

EDIT 1:

So while testing i found that a similar effect was being had when pressing the search button on the keyboard. I use the following code to dismiss the keyboard once search has been pressed:

- (void) searchBarSearchButtonClicked:(UISearchBar *)search
{
    [search resignFirstResponder];
}

Same effect here, works fine when i first start the app and do some searching, but after coming back to this screen from my modally presented view controllers pressing enter no longer dismisses the keyboard.

EDIT 2:

I even tried adding this piece of code in the searchBarSearchButtonClicked delegate method:

- (void) searchBarSearchButtonClicked:(UISearchBar *)search
{
    if ([search isFirstResponder]) {
        [search resignFirstResponder];
        NSLog(@"text field was first responder");
    } else {
        [search becomeFirstResponder];
        [search resignFirstResponder];
        NSLog(@"text field was not first responder");
    }
}

And both times it prints that the text field was the first responder. After returning from the modal views and clicking the search bar again it still says it is the first responder but it does not dismiss which is very odd. Any insight into this would be very helpful, Thanks.

Okay i figured out what the problem was. They first responder was being resigned but the keyboard was not disappearing because of a focus issue. There is a default behaviour on modal views to not dismiss the keyboard (which is not a bug apparently). So after returning from the modal view it was still having this behaviour (resigning first responder but not dismissing keyboard). The way i solved this was by placing the following code in both the modal views .m files:

- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}

This solved it for me. Then by either using:

[search resignFirstResponder];

or

[self.view endEditing: YES];

The keyboard will dismiss fine!

Instead of adding and removing your gestures in -(void)searchBarTextDidBeginEditing:(UISearchBar *)search { and -(void)searchBarTextDidEndEditing:(UISearchBar *)search { do it in viewWillAppear' (add here) and viewDidDisappear' (remove here).

and assuming your cancelGesture is a property with retain attribute. While adding gesture do this instead

UITapGestureRecognizer *gesture = [UITapGestureRecognizer new];
[gesture addTarget:self action:@selector(backgroundTouched:)];
self.cancelGesture = gesture;
[self.view addGestureRecognizer:self.cancelGesture];

and do remember to release cancelGesture in dealloc .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM