简体   繁体   English

检测点击 UIView 的“空白空间”

[英]Detect tap on UIView's "empty space"

I've got a view hierarchy that looks like that我有一个看起来像这样的视图层次结构

UIScrollView
 |
 +- UIView
     |
     +- UITextField
     +- UITextField
     +- UIButton

What I want is for user which tapped one of the text fields and sees the keyboard on the screen to be able to tap on an "empty space" of UIView to hide keyboard.我想要的是点击其中一个文本字段并在屏幕上看到键盘的用户能够点击 UIView 的“空白空间”来隐藏键盘。 So, I don't want, for instance, an event from UIButton to bubble up to UIView (that's exactly what happens if I add UITapGestureRecognizer to UIView).因此,例如,我不希望来自 UIButton 的事件冒泡到 UIView(如果我将 UITapGestureRecognizer 添加到 UIView 会发生这种情况)。

How can I achieve the desired functionality?我怎样才能实现所需的功能?

In your viewDidLoad method add this gesture recognizer: viewDidLoad方法中添加此手势识别器:

UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];
gestureRecognizer.cancelsTouchesInView = NO;
[self.view addGestureRecognizer:gestureRecognizer];

Then add the dismissKeyboard method: 然后添加dismissKeyboard方法:

- (void) dismissKeyboard{
   [YOURFIELDHERE resignFirstResponder];
} 

You also need to add this to make it so the buttons are still clickable and not overridden by the gesture recognizer: 您还需要添加此按钮以使按钮仍然可以单击并且不被手势识别器覆盖:

gestureRecognizer.delegate = self; // in viewDidLoad
<UIGestureRecognizerDelegate> //in your header file

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {

  if ([touch.view isKindOfClass:[UIButton class]]){
    return NO;
  }
  return YES; // handle the touch
}

I encounter this same problem and solve it with a naive solution. 我遇到了同样的问题,并用一个天真的解决方案来解决它。

  1. Change the View from an instance of UIView to an instance of UIControl so that it can handle touch events. 将视图从UIView的实例更改为UIControl的实例,以便它可以处理触摸事件。
  2. Create an IBAction method in the View Controller that handles the touch event. 在View Controller中创建一个处理触摸事件的IBAction方法。 In this case, we will resign any first responder from the view's subviews. 在这种情况下,我们将从视图的子视图中撤消任何第一响应者。

    - (IBAction)backgroundTapped:(id)sender { [contentView endEditing:YES]; }

    contentView is just the instance variable pointing to the View. contentView只是指向View的实例变量。 You can name it anything you want. 你可以任意命名。 When you passed the message endEditing to the View, it essentially tells its subviews to resign first responder, thus dismissing the keyboard. 当您将消息endEditing传递给View时,它实际上会告诉其子视图重新endEditing第一个响应者,从而解除键盘。

  3. Connect the target (View) and action (IBAction method you just created) via Interface Builder, by opening the connection inspector of the View, select Touch Up Inside and drag it to the File's Owner object, then select the name of the method. 通过Interface Builder连接目标(视图)和操作(刚刚创建的IBAction方法),打开View的connection inspector ,选择Touch Up Inside并将其拖到File的Owner对象,然后选择方法的名称。

Hopefully it helps. 希望它有所帮助。

I know it's a little late, but a quick, simple solution is the following: 我知道它有点晚了,但快速,简单的解决方案如下:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    [self.view endEditing:YES];
}

It gets called if you tap on any empty space. 如果点击任何空白区域,它就会被调用。

Mike Z's answer is good. Mike Z 的回答很好。 But I think the "if condition" below would be easier and simple in UIGestureRecognizerDelegate when you use Mike Z's answer .但是我认为当您使用 Mike Z's answer时,UIGestureRecognizerDelegate 中的“if 条件”会更容易和简单。

Especially when the subviews are not only a button type, they may also be UITableViewCell, Custom View, etc.特别是当子视图不仅是按钮类型的时候,还可能是 UITableViewCell、自定义视图等。

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    return touch.view == yourEmptySpaceView;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM