Question

There seems to be lots on this subject. But I couldn't get any of the solutions to work.

My code creates a tableView full of cells with varying contents (based on a JSON), the user should enter the info in each cell. The problem I am having is, when the user taps somewhere outside the cell (i.e. on the tableView background) I want the keyboard to dismiss.

didSelectRowAtIndexPath: method is not good.

touchesBegan: does not fire at all (tableView has user interaction enabled, but I assume there is some other reason).

I have added a gesture to the tableView, but then I cannot start editing.

I know the resignFirstResponder. But I don't know which field is being edited. so I think, I need to go with the endEditing: method. But I just couldn't get it called, when user touches outside of a cell.

Any help would appreciated.

Was it helpful?

Solution 2

Okay after lots of playing around a managed to figure (something) out, it is not great but works.

Most of the gaps around the table is taken up by section headers (a small amount by the cell walls). To get these areas to call a method I added a gesture to the section header like this;

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    NSString *sectionTitle = [self tableView:tableView titleForHeaderInSection:section];
    if (sectionTitle == nil)
    {
        return nil;
    }

    UILabel *label = [[UILabel alloc] init];
    label.frame = CGRectMake(20, 8, 320, 20);
    label.backgroundColor = [UIColor clearColor];
    label.textColor = [UIColor colorWithRed:76/255.0 green:86/255.0 blue:108/255.0 alpha:255/255.0];
    label.shadowColor = [UIColor grayColor];
    label.shadowOffset = CGSizeMake(-0.0, 0.0);
    label.font = [UIFont boldSystemFontOfSize:16];
    label.text = sectionTitle;

    UIView *view = [[UIView alloc] init];
    [view addSubview:label];

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(eventMenuTap)];
    [view addGestureRecognizer:singleTap];

    return view;
}

This also enabled me to customize the label for each section. The net reseult is now I have the keyboard closing when the table is scrolled and if (nearly) anywhere is clicked outside of a cell (i.e. a header) then the eventMenuTap is called.

-(void)eventMenuTap
{
    NSLog(@"Tap has begun...");
    [self.view endEditing:YES];
}

Thanks for all the ideas and help with this.

OTHER TIPS

If that is a textField as @JFS said, you can set the delegate and resign it in this below method.

- (BOOL)textFieldShouldReturn:(UITextField *)textField

Else If that is a textView, You can add a toolbar with done button as inputAccessoryView to your textView and resign your textView.

I am having two more ideas

Bad Idea:
Try to make an invisible button in the cell background and add an action method to resign it. But this will get confused, when you are using didSelectRowAtIndexPath: method of your UITableView.

Good Idea:(Good one)
UITableView surely will have UIScrollview. So in the scrollViewDidScroll: method, set [self endEditing:YES] will surely work.

Good Idea 2 Create a new View or Button and place it on top of the all views, when a textView is in editing and call the endEditing: method when user touches the view or button.

TO GET A TOUCH DETECTION IN TABLEVIEW:

Some of these Q&A will help you.

https://stackoverflow.com/a/8787019/1083859

Why does my UITableView not respond to touchesBegan?

https://stackoverflow.com/a/8786706/1083859

For any passersby, the simplest and most effective solution I have found requires 2 things:

1: Subclass your table view and add the following to its .m:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    // send your own dismiss message; you can use self.delegate to refer to TV's TVC...
    [((SearchVC *)((UITableViewController *)self.delegate).parentViewController).searchBar resignFirstResponder]; 

    // crucial!
    [super touchesBegan:touches withEvent:event];
}

2: Add the following to your TVC:

- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    // send your own dismiss message...
    [((SearchVC *)self.parentViewController).searchBar resignFirstResponder];
}

This works beautifully for me. I initially tried adding touchesBegan to my subclassed cell, but found that was insufficient and, after adding these two things, superfluous.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top