Reputation: 10196
I have a UITableView with an associated UITableViewController. However, I've modified the table to also have a view with a textfield subview.
As always, I want the keyboard to disappear when the user hits 'done' (easy) and when they touch anywhere else on screen other than the textfield (hard, stuck!).
The normal way to achieve this is to change the class to UIControl so it can handle actions... but I can't do this for my UITableView/UITableViewController combination.
How can I solve this problem?
Upvotes: 2
Views: 9812
Reputation: 10174
Using alloc breaks with ARC enabled
Just add the following to the viewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//where text field is a @property (nonatomic,retain) IBOutlet to your textfield
[textField resignFirstResponder];
}
Upvotes: 2
Reputation: 10828
U can handle user touches by adding a UITapGestureRecognizer
to your view.
For example if u don't want to enable row selection in your tableView u call self.tableView.allowsSelection = NO;
But if u still want to detect user touches u add a UITapGestureRecognizer
to your tableView (or to tableView.superview).
U can have more control if u implement the UIGestureRecognizerDelegate
, this way u can detect and then choose witch touches to receive and witch not.
To do that just add this code to your UITableViewController
:
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView.allowsSelection = NO;
UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(viewTapped:)];
tgr.delegate = self;
[self.tableView addGestureRecognizer:tgr]; // or [self.view addGestureRecognizer:tgr];
[tgr release];
}
- (void)viewTapped:(UITapGestureRecognizer *)tgr
{
NSLog(@"view tapped");
// remove keyboard
}
// this is optional, it let u choose witch touches to receive, for example here I'm checking if user has tapped on a textField
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UITextField class]]) {
NSLog(@"User tapped on UITextField");
}
return YES; // do whatever u want here
}
Upvotes: 6
Reputation: 3042
When a row is tapped the didSelectRowAtIndexPath
is called. If a textField located inside inside a row is tapped then the textfield delegate is called.
So in addition to your done button method, in didSelectRowAtIndexPath
add a check for the text field being first responder and ask it to resign. Assuming a the selected indexPath is not the row of the textfield.
Upvotes: 0
Reputation: 523
A normal practice is to put a custom UIButton( it becomes visible only when uitextfield begins editing ) behind keyboard view, and when user clicks on screen he actually clicks on that button, and associated selector can resign first responder.
-(void) closeKeyboard:(UIButton *) b {
[self.view endEditing:YES]; //assuming self is your top view controller.
[b setHidden:YES];
}
Using endEditing is better, cause it loops through all subviews and looks for current first responder.
Upvotes: 4