The runner doesn't answer

I would like to use the touchhesBegan method to know when the user taps on it outside of the UITextField in my TableView.

I have a UIView that contains a TableView and I have the following method:

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

NSLog(@"See a tap gesture");
UITouch *touch = [touches anyObject];
    //find first response view
    for (UIView *view in [self.view subviews]) {
        if ([view isFirstResponder]) {
            [view resignFirstResponder];

[super touchesBegan:touches withEvent:event];



My self.view and my self.tableView both have a userInteractionEnabled value for YES, but for some reason the touchsBegan never starts. Any idea?


source to share

4 answers

If yours UIView

contains yours UITableView

, then the table view is at the top of the responder chain and touch events will not show up in your view. But there might be a better way to do it. What are you after?


Implement a method UITextFieldDeletate


to intercept the click of the Return button:

-(BOOL)textFieldShouldReturn:(UITextField *)textField {
   [textField resignFirstResponder];
   return YES;


Also, UITableViewDelegate is a UIScrollViewDelegate, so you can hook into these methods to determine when the user is interacting with the table view.

In general, I think you don't need to worry about giving up the keyboard immediately when the user touches it, especially if you have other text inputs on the same screen.


Ok, fair enough, but things start to get complicated when you intercept touch events with complex transparent views (they can get expensive too), etc. And you never know about the consequences that will arise in the future, not only for the user, but also for you when you want to update the application in the future.

Why not keep it simple? How about just "Done" UIBarButtonItem

, or a slightly translucent UIToolbar

one that slides up the keyboard / compiler ala Mobile Safari? These solutions are acceptable to the user and can make life easier. They certainly make the process easier by dividing artifacts and functionality into modular blocks.

One final note

Using UITapGestureRecognizer I think it will be difficult to get right in your situation. I'm concerned that any connection recognizer you add to the table view will prevent things like selecting a row or moving the control to another UI element (textbox, radio button, etc.).



Make sure you configure your object to handle these touch events:

[myButton addTarget:self action:@selector(buttonTouch:withEvent:) forControlEvents:UIControlEventTouchUpInside];


And then handle the touch event in the method you declared:

- (IBAction) buttonTouch:(id) sender withEvent:(UIEvent *) event


Updated for UIView (assuming you already have an output created and connected):

[myView addTarget:self action:@selector(myTouchEvent:withEvent:) forControlEvents:UIControlEventTouchUpInside];


And then:

- (IBAction) myTouchEvent:(id) sender withEvent:(UIEvent *) event


Now that I understand what you are trying to do (disable keyboard when tapping outside of the textbox), there is a simple solution that works well with almost every scenario).

Step 1 - Create a button with a size similar to the view that the TableViewController (large button) is placed in. Step 2 - Send this button back (Editor-> Arrange-> Send Back) Step 3 - Connect the IBAction to this button and name it rejectKeyboardButtonPressed (prompt, if you are not using the editor helper yet, you should be) Step 4 - Insert the method IBAction (if your TextField is called myTextField):

[myTextField resignFirstResponder];


Step 5 - Run it. Whenever you touch anywhere in the view outside of the text box, it rejects the keyboard.

This is the technique I use almost any time I put a TextField in a view and you need to reject KB when touching outside of the TextField.



Try adding a gesture recognizer to your table view. So you should be able to allow normal behavior as well as capture the tap event to do your extra stuff.



I implemented similar functionality in one of my applications, I used textboxes, not textboxes, but it should still work. I used

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [textField reresignFirstResponder];


Without any checks, if the user picks up the resignFirstResponder method is called, but if the user clicks on the textView then this forces him to become the first responder again, which will not cause visible changes. I have implemented this concept in an application with 9 textboxes in one view and I haven't had any problems yet.



All Articles