xcode 创建一个捕获点击但对所有其他手势透明的 UIView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13412906/
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 02:06:59  来源:igfitidea点击:

Creating a UIView that captures taps, but is transparent to all other gestures

iosxcodeuser-interfaceuiscrollviewgestures

提问by mjh

I want to achieve the following.

我想实现以下目标。

Scenario: The iOS keyboard is on-screen while the user is typing into a particular text field. The user can tap anywhere outside of the keyboard and text field to dismiss the keyboard (without activating any buttons which are visible). Also, the user can dragoutside of the keyboard and observe the normal drag behavior on some arrangement of scrollable views.

场景:当用户在特定文本字段中键入时,iOS 键盘在屏幕上。用户可以点击键盘和文本字段之外的任何地方来关闭键盘(不激活任何可见的按钮)。此外,用户可以在键盘外拖动并观察某些可滚动视图排列上的正常拖动行为。

Conceptually, I'm placing a “cover” UIViewover most of the screen which behaves such that:

从概念上讲,我UIView在大部分屏幕上放置了一个“封面” ,其行为如下:

  1. If the user taps on the cover, then I capture that tap (so that I can, e.g., dismiss the keyboard). This is easy to achieve by intercepting touch events in a UIViewsubclass or using a tap gesture recognizer.

  2. If the user drags on the cover, then the cover ignoresor forwardsthese touches; these are received by the layers underneath just as they would have been without a cover.

  1. 如果用户点击封面,那么我会捕获该点击(以便我可以,例如,关闭键盘)。这很容易通过拦截UIView子类中的触摸事件或使用点击手势识别器来实现。

  2. 如果用户在封面上拖动,则封面忽略转发这些触摸;这些被下面的层接收,就像没有盖子一样。

So: the user should be able to scroll content underneath the cover, but not tap content underneath the cover. A tap “outside” of the keyboard and text field should dismiss the keyboard (and cover), but should not activate anything.

所以:用户应该能够滚动封面下方的内容,但不能点击封面下方的内容。点击键盘和文本字段的“外部”应该关闭键盘(和封面),但不应激活任何内容。

How can I achieve this?

我怎样才能做到这一点?

回答by cwehrung

Add the tap gesture the usual way:

以通常的方式添加点击手势:

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[self.view addGestureRecognizer:tapGesture];

But what you may be looking for is this :

但您可能正在寻找的是:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
    {    
        return YES;
    }

Documentation says : This method is called when recognition of a gesture by either gestureRecognizer or otherGestureRecognizer would block the other gesture recognizer from recognizing its gesture. (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIGestureRecognizerDelegate_Protocol/index.html#//apple_ref/occ/intf/UIGestureRecognizerDelegate)

文档说:当gestureRecognizer 或otherGestureRecognizer 识别手势会阻止其他手势识别器识别其手势时,将调用此方法。(https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIGestureRecognizerDelegate_Protocol/index.html#//apple_ref/occ/intf/UIGestureRecognizerDelegate

This way, you may be sure it's totally transparent, and also that nothing will prevent your recognizer from being called.

通过这种方式,您可以确定它是完全透明的,并且没有什么可以阻止您的识别器被调用。

回答by sust86

A custom view which forwards all touches it receives:

转发它收到的所有触摸的自定义视图:

class CustomView: UIView {

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {

        var hitView = super.hitTest(point, withEvent: event)

        if hitView == self {
            return nil
        }

        return hitView
    }    
}

From there you can go different ways to just make use of tap gestures. Either observe the UIEvent for its touches, or use a gesture recognizer.

从那里你可以通过不同的方式来使用点击手势。要么观察 UIEvent 的触摸,要么使用手势识别器。

回答by Holger Sindbaek

1: Add a tap gesture recognizer to the view:

1:在视图中添加点击手势识别器:

    //Adding tap gesture
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTapGesture:)];
    tapGesture.numberOfTapsRequired = 1;
    [self.view addGestureRecognizer:tapGesture];

2: In handleTapGesture you resignFirstResponder of the keyboard

2:在handleTapGesture中,你退出了键盘的FirstResponder

- (void)handleTapGesture:(UITapGestureRecognizer *)sender {
    if (sender.state == UIGestureRecognizerStateRecognized) {
       //Resign first responder for keyboard here
    }
}

Elaborated a bit on the answer above. UIGestureRecognizerStateRecognized makes sure it's single tab events that gets recognized.

对上面的答案进行了详细说明。UIGestureRecognizerStateRecognized 确保它是被识别的单个选项卡事件。

Is this the functionality you where after?

这是您追求的功能吗?