Skip to content

Instantly share code, notes, and snippets.

@GiK
Created October 5, 2011 19:37
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save GiK/1265436 to your computer and use it in GitHub Desktop.
Save GiK/1265436 to your computer and use it in GitHub Desktop.
Using gesture recognizers to dismiss a keyboard overlaying a UISplitViewController
/*
This sample uses your application's keyWindow - the window that all other views hang from. Since UIWindow is simply a subclass of UIView, we can add gesture recognizers to it.
No matter where you tap or scroll - the master view's table view, or a map in the detail view - the keyboard will be dismissed and your pan/tap gesture continues unhindered.
*/
// Adopt UIGestureRecognizerDelegate and UISearchBarDelegate protocols in .h
@interface DetailViewController ()
// Obviously you're free to add long press, multiple tap, and swipe gestures.
@property (nonatomic, retain) UITapGestureRecognizer *tapGestureRecognizer;
@property (nonatomic, retain) UIPanGestureRecognizer *panGestureRecognizer;
@end
@implementation DetailViewController
@synthesize tapGestureRecognizer = _tapGestureRecognizer;
@synthesize panGestureRecognizer = _panGestureRecognizer;
- (void)dealloc {
//...
[_tapGestureRecognizer release];
[_panGestureRecognizer release];
[super dealloc];
}
#pragma mark -
#pragma mark UISearchBarDelegate methods
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar {
// Add the gesture recognizers to keyWindow when the user starts editing in the search bar.
// The keyboard appears above keyWindow, so typing won't trigger the recognizers.
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapFrom:)];
tap.delegate = self;
self.tapGestureRecognizer = tap;
[tap release];
[keyWindow addGestureRecognizer:self.tapGestureRecognizer];
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
pan.delegate = self;
self.panGestureRecognizer = pan;
[pan release];
[keyWindow addGestureRecognizer:self.panGestureRecognizer];
return YES;
}
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar {
UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
// Remove the gesture recognizers when the keyboard is dismissed.
[keyWindow removeGestureRecognizer:self.tapGestureRecognizer];
[keyWindow removeGestureRecognizer:self.panGestureRecognizer];
// Or you could iterate through the array of gesture recognizers on keyWindow...
/*
[[keyWindow gestureRecognizers] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if (obj == self.tapGestureRecognizer || obj == self.panGestureRecognizer) {
[keyWindow removeGestureRecognizer:obj];
}
}];
*/
return YES;
}
#pragma mark -
#pragma mark UIGestureRecognizerDelegate methods
- (void)handleTapFrom:(UIGestureRecognizer *)recognizer {
// You don't want to dismiss the keyboard if a tap is detected within the bounds of the search bar...
CGPoint touchPoint = [recognizer locationInView:self.view];
if (!CGRectContainsPoint(self.searchBar.frame, touchPoint)) {
[self.searchBar resignFirstResponder];
}
}
- (void)handlePanFrom:(UIGestureRecognizer *)recognizer {
// It's not likely the user will pan in the search bar, but we can capture that too.
CGPoint touchPoint = [recognizer locationInView:self.view];
if (!CGRectContainsPoint(self.searchBar.frame, touchPoint)) {
[self.searchBar resignFirstResponder];
}
}
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
// Return YES to prevent this gesture from interfering with, say, a pan on a map or table view, or a tap on a button in the tool bar.
return YES;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment