UITableView - resign first responder on outside touch

半世苍凉 提交于 2020-01-01 19:36:12

问题


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?


回答1:


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
}



回答2:


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.




回答3:


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]; 
}



回答4:


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.



来源:https://stackoverflow.com/questions/11809816/uitableview-resign-first-responder-on-outside-touch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!