1

So this is what my view looks like - there's a text field on top acting as a search bar, and then below that there is a table view. I want to implement backgroundTap, so that when I tap anywhere the keyboard goes away if it is up.

I've tried doing this by changing the view to be a UIControl and adding this -

- (IBAction)backgroundTap:(id)sender{
NSLog(@"BACKGROUND TAPPED");
[self.searchBar resignFirstResponder];

}

This doesn't work - the backgroundTap method doesn't run when I click on the tableView (and I've connected things properly).

I also tried overriding the touchesBegan method for the table view, but that didn't work either.

How do I achieve what I'm trying to achieve?

EDIT-

I tried to do this-

  tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(backgroundTap:)];
     tapRecognizer.numberOfTapsRequired = 1;
     [self.view addGestureRecognizer:tapRecognizer];
     tapRecognizer.enabled = NO;
praks5432
  • 7,246
  • 32
  • 91
  • 156
  • `tapRecognizer.enabled = NO;` means, surprisingly enough, that your tap recognizer is not enabled :) Also, like I said in an another comment, you have other views on top of `self.view`, so any gesture recognizer on `self.view` won't get fired anyway – TotoroTotoro Dec 19 '13 at 00:51
  • Somehow I think this is a duplicate of this http://stackoverflow.com/questions/20347284/dismiss-keyboard-when-touch-began-on-uitableview-and-googlemaps-view/20347749#20347749 – Joshua Dec 19 '13 at 02:24

2 Answers2

1

Solution 1

When your search bar becomes a first responder (starts accepting keyboard input), create a new view and place it on top of your table view. Make it transparent, and add a tap gesture recognizer to it. In the tap handler, call [self.searchBar resignFirstResponder], and remove or hide this transparent view.

Here's how you can create this overlay view:

// declare overlayView as a property or an ivar
_overlayView = [[UIView alloc] initWithFrame:self.tableView.frame]; 
_overlayView.alpha = 0; // make transparent 
[self.view insertSubview:_overlayView aboveSubview:self.tableView];

Solution 2

You can resign first responder inside the UITableViewDelegate method tableView:didSelectRowAtIndexPath: This way a single tap will dismiss the keyboard, and also trigger whatever action you've programmed for tapping on cells.

TotoroTotoro
  • 17,524
  • 4
  • 45
  • 76
  • how do I programmatically create a view that is guaranteed to cover only the table view? – praks5432 Dec 19 '13 at 00:33
  • `UIView *overlayView = [[UIView alloc] initWithFrame:self.tableView.frame]; [self.view insertSubview:overlayView aboveSubview:self.tableView];` – TotoroTotoro Dec 19 '13 at 00:35
  • wait, but won't this make my cells not clickable, like the above solution? – praks5432 Dec 19 '13 at 00:39
  • Yes, and I'd say that is a good thing. It's best for each interaction to do one thing, and not several unrelated things. In this case it's completing the input into the search bar. After that first tap your overlay view disappears and you can tap on cells again. – TotoroTotoro Dec 19 '13 at 00:41
  • ohhh - and is this overlay view automatically transparent? – praks5432 Dec 19 '13 at 00:41
  • No, you need to set its alpha to 0 for it to be transparent. – TotoroTotoro Dec 19 '13 at 00:42
  • Regarding your earlier comment: you can always resign first responder inside the delegate method `tableView:didSelectRowAtIndexPath:` This way a single tap will dismiss the keyboard, and trigger whatever action you've programmed for tapping on cells. – TotoroTotoro Dec 19 '13 at 00:43
  • so backgroundTap isn't being run - I set the alpha to 1, and the view wasn't on the screen - how do I position properly? – praks5432 Dec 19 '13 at 00:50
  • Seem my comment below your question. There are problems with your code. I recommend trying my solution, which I've used before to solve this exact problem. – TotoroTotoro Dec 19 '13 at 00:52
0

You want to use UITapGestureRecognizer.

In your .h file:

@interface viewController: UIViewController <UITextFieldDelegate>
{
    UITapGestureRecognizer *tapRecognizer;
}

In your your .m file:

 - (void)viewDidLoad {
     yourTextField.delegate = self;

     tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected:)];
     tapRecognizer.numberOfTapsRequired = 1;
     [self.view addGestureRecognizer:tapRecognizer];
     tapRecognizer.enabled = NO;

 }

 -(void)tapDetected {
     [yourTextField resignFirstResponder];
 }
JustAnotherCoder
  • 2,565
  • 17
  • 38