虽然大多数苹果文档都写得很好,但我认为'Event Handling Guide for iOS‘是个例外。我很难清楚地理解这里所描述的内容。
文件上说,
在命中测试中,窗口在视图层次结构的最顶层视图上调用
hitTest:withEvent:
;此方法通过递归地对视图层次结构中返回YES的每个视图调用pointInside:withEvent:
,沿着层次结构向下进行,直到找到发生触摸的子视图。这个视图变成了“命中测试”视图。
那么,系统是否只调用最顶层视图的hitTest:withEvent:
,并调用所有子视图的pointInside:withEvent:
,如果从特定子视图返回的结果为YES,则调用该子视图的子类的pointInside:withEvent:
?
发布于 2011-02-11 03:07:56
这似乎是一个很基本的问题。但我同意你的观点,这份文件不像其他文件那么清晰,所以我的答案是。
UIResponder中的hitTest:withEvent:
实现如下所示:
它调用self
pointInside:withEvent:
,hitTest:withEvent:
返回nil
。故事的结尾。hitTest:withEvent:
消息发送到它的子视图。它从顶层子视图开始,一直到其他视图,直到某个子视图返回非nil
对象,或者所有子视图都收到消息。nil
对象,则第一个hitTest:withEvent:
将返回该对象。故事的结尾。nil
对象,则第一个hitTest:withEvent:
返回此过程会递归重复,因此通常最终会返回视图层次结构的叶视图。
但是,您可能会重写hitTest:withEvent
来做一些不同的事情。在许多情况下,重写pointInside:withEvent:
更简单,并且仍然提供了足够的选项来调整应用程序中的事件处理。
发布于 2011-02-11 03:08:38
我认为你混淆了子类化和视图层次结构。医生说的内容如下。假设你有这样的视图层次结构。关于层次,我不是在谈论类层次,而是视图层次中的视图,如下所示:
+----------------------------+
|A |
|+--------+ +------------+ |
||B | |C | |
|| | |+----------+| |
|+--------+ ||D || |
| |+----------+| |
| +------------+ |
+----------------------------+
假设你把手指放在D
里面。下面是将要发生的事情:
在视图hierarchy.
pointInside:withEvent:
的最顶层视图A
上调用hitTest:withEvent:
,在每个视图上递归调用。pointInside:withEvent:
在A
上调用,returns YES
pointInside:withEvent:
在B
上调用,returns YES
pointInside:withEvent:
在C
上调用,returns YES
在D
上调用
YES
的视图上,它将向下查看层次结构,以查看发生触摸的子视图。在这种情况下,从A
,C
和D
,它将是命中测试视图发布于 2015-07-15 11:08:41
我发现这个Hit-Testing in iOS非常有帮助
- (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:
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
}
https://stackoverflow.com/questions/4961386
复制相似问题