面试被问过两次了的一个问题,记录一下: 假如一个 UIView(我们称作 FatherView),有一个 subview(我们称作 ChildView),这个 ChildView 在 FatherView 的 frame 外部,那么默认情况下,这个 ChildView 被点击的时候,并不会触发 FatherView 的点击响应链(这是合情合理的,FatherView 所在的位置都没被点击,它不遍历 subviews,不作回应是正常的),这时候怎样才能让这个 ChildView 相应点击事件?
其实思路是很简单的,监控屏幕上的所有点击事件的区域,如果这个区域和我们的 UIView 以及其 subview 的 CGRect 有重合,就作出反应。
也很容易查到 UIKit 提供了一个现成的方法来做到这件事:
代码是很简单的,现在让灰色的视图作为父视图,蓝色、红色的作为子视图,只要灰色视图实现了上述方法,就可以让蓝色视图像红色视图一样,可以相应点击事件。
完整 Demo Github 地址
至此都是很简单的内容,需要注意的如下:
HitTest
会被频繁执行,你随便点击一个空白处,这个方法都会执行,这必然带来性能消耗,这也是 Apple 默认不使用这个方式的原因之一吧 HitTest
会使得我们的蓝色的 UIView 可以相应点击,但是它被点击的之后,执行的方法我们应该按常规的方式写(比如给它加一个 UIGestureRecognizer
,然后让这个 Gesture 有一个对应的 selector)。如果把需要执行的方法写在了 HitTest
里面,写在 return result
之前的话,我发现这些方法会多执行一次(在我当前写的这个简单 demo 里,我发现点击任意地方, HitTest
方法都会连续执行两次) 延伸阅读 - 深入浅出 iOS 事件机制