xcode Swift:在另一个 UIView 下对 UIView 进行 hitTest

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

Swift: hitTest for UIView underneath another UIView

iosxcodeswiftuiviewhittest

提问by Kashif

I have TransparentUIView on top of RedOrGreenUIView. TransparentUIView has a UILongPressGestureRecognizer attached to it. Once user begins a long touch on it, I check for .Changed status of this LongPressGesture, and execute below hitTest:

我在 RedOrGreenUIView 上有 TransparentUIView。TransparentUIView 附加了一个 UILongPressGestureRecognizer。一旦用户开始长时间触摸它,我就会检查这个 LongPressGesture 的 .Changed 状态,并在下面的 hitTest 中执行:

var p:CGPoint = rec.locationInView(self.view)
var selectedView = view.hitTest(p, withEvent: nil)
if selectedView != nil {
   if selectedView == TransparentUIView {
       println("TransparentUIView is being touched")
   }
}

I get TransparentView as selectedView fine. However I need to be able to conduct a hitTest on RedOrGreenUIView at the same time, which is underneath TransparentUIView. I cant get my head around to accomplishing this. Please help.

我得到 TransparentView 作为 selectedView 很好。但是,我需要能够同时对 RedOrGreenUIView 进行 hitTest,它位于 TransparentUIView 之下。我无法解决这个问题。请帮忙。

采纳答案by Shamas S - Reinstate Monica

If one UIView gets touches, others underneath don't get any.

如果一个 UIView 被触摸,则下面的其他人不会得到任何触摸。

So either you can have a central class that passes touches to both your UIView objects, or the first UIView, the one that is on top, passes its UITouch object to the UIView underneath and conducts the hitTest.

因此,您可以拥有一个将触摸传递给两个 UIView 对象的中央类,或者第一个 UIView(位于顶部的那个)将其 UITouch 对象传递给下面的 UIView 并进行 hitTest。

回答by Suraj K Thomas

Create a custom view for your container and override the pointInside: message to return NO when the point isn't within an eligible child view, like this:

为您的容器创建自定义视图并覆盖 pointInside: 消息以在该点不在符合条件的子视图中时返回 NO,如下所示:

@interface PassthroughView : UIView
@end

@implementation PassthroughView
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    for (UIView *view in self.subviews) {
        if (!view.hidden && view.alpha > 0 && view.userInteractionEnabled && [view pointInside:[self convertPoint:point toView:view] withEvent:event])
            return YES;
    }
    return NO;
}
@end

swift version

快速版

class PassThroughView: UIView {

     override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
            for subview in subviews as [UIView] {
                if !subview.hidden && subview.alpha > 0 && subview.userInteractionEnabled && subview.pointInside(convertPoint(point, toView: subview), withEvent: event) {
                    return true
                }
            }
            return false
        }
    }

回答by byJeevan

Swift 4 version :

斯威夫特 4 版本:

 override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        for subview in YourView.subviews as [UIView] {

            if !subview.isHidden && subview.alpha > 0 && subview.isUserInteractionEnabled && subview.point(inside:point, with: event) {
                return true
            }
        }

    return false
 }

回答by A. van Weije

I am currently working on a transparent Help Overlay for iOS apps and was looking for a good answer on this myself.

我目前正在为 iOS 应用程序开发一个透明的帮助覆盖,并且我自己也在寻找一个很好的答案。

I couldn't really find anything, so decided to look a bit further. The apple documentation on hitTest says it doesn't include views that have a transparency of < 0.1, are hidden or have userInteractionEnabled to false.

我真的找不到任何东西,所以决定再看一下。关于 hitTest 的苹果文档说它不包括透明度 < 0.1、隐藏或将 userInteractionEnabled 设置为 false 的视图。

That last one gave me an idea and it's something that seems to work pretty good.

最后一个给了我一个想法,它似乎工作得很好。

Try the following (I still need to test it further, but it seems to be allright):

尝试以下操作(我仍然需要进一步测试,但似乎没问题):

var p:CGPoint = rec.locationInView(self.view)

TransparentUIView.isUserInteractionEnabled = false

var selectedView = view.hitTest(p, withEvent: nil)

TransparentUIView.isUserInteractionEnabled = true

if selectedView != nil {
    if selectedView == TransparentUIView {
        println("TransparentUIView is being touched")
    }
}