首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >iOS的事件处理- hitTest:withEvent:和pointInside:withEvent:是如何相关的?

iOS的事件处理- hitTest:withEvent:和pointInside:withEvent:是如何相关的?
EN

Stack Overflow用户
提问于 2011-02-11 02:57:48
回答 7查看 82.9K关注 0票数 151

虽然大多数苹果文档都写得很好,但我认为'Event Handling Guide for iOS‘是个例外。我很难清楚地理解这里所描述的内容。

文件上说,

在命中测试中,窗口在视图层次结构的最顶层视图上调用hitTest:withEvent:;此方法通过递归地对视图层次结构中返回YES的每个视图调用pointInside:withEvent:,沿着层次结构向下进行,直到找到发生触摸的子视图。这个视图变成了“命中测试”视图。

那么,系统是否只调用最顶层视图的hitTest:withEvent:,并调用所有子视图的pointInside:withEvent:,如果从特定子视图返回的结果为YES,则调用该子视图的子类的pointInside:withEvent:

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-02-11 03:07:56

这似乎是一个很基本的问题。但我同意你的观点,这份文件不像其他文件那么清晰,所以我的答案是。

UIResponder中的hitTest:withEvent:实现如下所示:

它调用self

  • If的pointInside:withEvent:
  • is NO,hitTest:withEvent:返回nil。故事的结尾。
  • 如果返回的结果是YES,它会将hitTest:withEvent:消息发送到它的子视图。它从顶层子视图开始,一直到其他视图,直到某个子视图返回非nil对象,或者所有子视图都收到消息。
  • 如果某个子视图第一次返回非nil对象,则第一个hitTest:withEvent:将返回该对象。故事的结尾。
  • 如果没有任何子视图返回非nil对象,则第一个hitTest:withEvent:返回

此过程会递归重复,因此通常最终会返回视图层次结构的叶视图。

但是,您可能会重写hitTest:withEvent来做一些不同的事情。在许多情况下,重写pointInside:withEvent:更简单,并且仍然提供了足够的选项来调整应用程序中的事件处理。

票数 178
EN

Stack Overflow用户

发布于 2011-02-11 03:08:38

我认为你混淆了子类化和视图层次结构。医生说的内容如下。假设你有这样的视图层次结构。关于层次,我不是在谈论类层次,而是视图层次中的视图,如下所示:

代码语言:javascript
复制
+----------------------------+
|A                           |
|+--------+   +------------+ |
||B       |   |C           | |
||        |   |+----------+| |
|+--------+   ||D         || |
|             |+----------+| |
|             +------------+ |
+----------------------------+

假设你把手指放在D里面。下面是将要发生的事情:

在视图hierarchy.

  • pointInside:withEvent:的最顶层视图A上调用
  1. hitTest:withEvent:,在每个视图上递归调用。
    1. pointInside:withEvent:A上调用,returns YES
    2. pointInside:withEvent:B上调用,returns YES
    3. pointInside:withEvent:C上调用,returns YES

D上调用

  1. 在返回YES的视图上,它将向下查看层次结构,以查看发生触摸的子视图。在这种情况下,从ACD,它将是命中测试视图
票数 302
EN

Stack Overflow用户

发布于 2015-07-15 11:08:41

我发现这个Hit-Testing in iOS非常有帮助

代码语言:javascript
复制
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (!self.isUserInteractionEnabled || self.isHidden || self.alpha <= 0.01) {
        return nil;
    }
    if ([self pointInside:point withEvent:event]) {
        for (UIView *subview in [self.subviews reverseObjectEnumerator]) {
            CGPoint convertedPoint = [subview convertPoint:point fromView:self];
            UIView *hitTestView = [subview hitTest:convertedPoint withEvent:event];
            if (hitTestView) {
                return hitTestView;
            }
        }
        return self;
    }
    return nil;
}

编辑Swift 4:

代码语言:javascript
复制
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    if self.point(inside: point, with: event) {
        return super.hitTest(point, with: event)
    }
    guard isUserInteractionEnabled, !isHidden, alpha > 0 else {
        return nil
    }

    for subview in subviews.reversed() {
        let convertedPoint = subview.convert(point, from: self)
        if let hitView = subview.hitTest(convertedPoint, with: event) {
            return hitView
        }
    }
    return nil
}
票数 50
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4961386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档