xcode UITableView - 退出外部触摸的第一响应者

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11809816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 01:08:09  来源:igfitidea点击:

UITableView - resign first responder on outside touch

iosxcodecocoa-touchuitableview

提问by ConfusedNoob

I have a UITableView with an associated UITableViewController. However, I've modified the table to also have a view with a textfield subview.

我有一个带有关联 UITableViewController 的 UITableView。但是,我已经修改了表格,使其也有一个带有文本字段子视图的视图。

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.

实现这一点的正常方法是将类更改为 UIControl 以便它可以处理操作......但我不能为我的 UITableView/UITableViewController 组合这样做。

How can I solve this problem?

我怎么解决这个问题?

回答by Eyal

U can handle user touches by adding a UITapGestureRecognizerto 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 UITapGestureRecognizerto 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:

你可以通过UITapGestureRecognizer在你的视图中添加 a来处理用户的触摸。
例如,如果您不想在您的 tableView 中启用行选择,请调用self.tableView.allowsSelection = NO;
但如果您仍想检测用户触摸UITapGestureRecognizer,请向您的 tableView(或 tableView.superview)添加一个。
如果你实现了UIGestureRecognizerDelegate,你可以有更多的控制,这样你就可以检测然后选择接收和不接收。
为此,只需将此代码添加到您的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

// 这是可选的,它让你选择要接收的女巫触摸,例如这里我正在检查用户是否点击了 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
}

回答by Bogdan Andresyuk

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.

通常的做法是将自定义 UIButton(仅当 uitextfield 开始编辑时才可见)放在键盘视图后面,当用户单击屏幕时,他实际上单击了该按钮,并且关联的选择器可以退出第一响应者。

-(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.

使用 endEditing 更好,因为它会遍历所有子视图并查找当前的第一响应者。

回答by PicoCreator

Using alloc breaks with ARC enabled

在启用 ARC 的情况下使用 alloc 中断

Just add the following to the viewController

只需将以下内容添加到 viewController

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    //where text field is a @property (nonatomic,retain) IBOutlet to your textfield
    [textField resignFirstResponder]; 
}

回答by Olaf

When a row is tapped the didSelectRowAtIndexPathis called. If a textField located inside inside a row is tapped then the textfield delegate is called.

当一行被点击时didSelectRowAtIndexPath调用。如果点击位于行内的 textField,则调用 textfield 委托。

So in addition to your done button method, in didSelectRowAtIndexPathadd 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.

因此,除了您的完成按钮方法之外,还要didSelectRowAtIndexPath检查作为第一响应者的文本字段并要求其辞职。假设选定的 indexPath 不是文本字段的行。