Similar to this question I have a custom subclass of UITableViewCell that has a UITextField. Its working fine except the keyboard for doesn\'t go away when the user touches
[Edited: removed previous attempt which didn't always work, this one does]
OK, I finally figured a solution that fully works. I subclassed UITableView and overrode the hitTest:withEvent: method. It gets invoked for all touches anywhere in the table view, the only other possible touches are in the navbar or keyboard and the tableview's hitTest doesn't need to know about those.
This keeps track of the active cell in the table view, and whenever you tap a different cell (or non-cell) it sends a resignFirstResponder to the cell going inactive, which gives it a chance to hide its keyboard (or its datepicker).
-(UIView*) hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
// check to see if the hit is in this table view
if ([self pointInside:point withEvent:event]) {
UITableViewCell* newCell = nil;
// hit is in this table view, find out
// which cell it is in (if any)
for (UITableViewCell* aCell in self.visibleCells) {
if ([aCell pointInside:[self convertPoint:point toView:aCell] withEvent:nil]) {
newCell = aCell;
break;
}
}
// if it touched a different cell, tell the previous cell to resign
// this gives it a chance to hide the keyboard or date picker or whatever
if (newCell != activeCell) {
[activeCell resignFirstResponder];
self.activeCell = newCell; // may be nil
}
}
// return the super's hitTest result
return [super hitTest:point withEvent:event];
}
In my UITableViewCell subclasses that have a UITextField, I add the following code to get rid of the keyboard (or date picker, which slides up just like the keyboard):
-(BOOL)resignFirstResponder
{
[cTextField resignFirstResponder];
return [super resignFirstResponder];
}
Yay!
That is a very good solution, the best I've found on the net. The only glitch I've discovered is that if you go from one cell with a textfield to another, the keyboard dismisses and reappears resulting in a jerky type animation.
I think you're on the right track, but touchesBegan:withEvent:
is a UIResponder method, so you'd actually have to override it in a UIView subclass rather than in your UIViewController subclass. Your options are:
touchesBegan:withEvent:
there.tableView:didSelectRowAtIndexPath
in your UITableView's delegate.