CALayer 的 hittest 可以返回一个点所在点最远的layer。那么这个检查sublayer的顺序是怎么样的呢?
为了得到这个顺序,我们先用method swizzling 在 [CALayer hittest:] 里面加上一行打印当前layer 的代码
为了方便再加上打印sublayers的方法
然后在view controller 随便创建一个view, 加入一些 layer 并调用 hittest 来进行
得到如下输出:
从上面我们可以看到,hittest 是用的DFS来遍历图层树,而且不存在短路设置(layer3, layer 31)(其实有短路的,当maskToBounds = YES 的时候就可以有短路了,会在接下来的部分里说明),所有的layer都会被检查一遍,但是最后返回的结果是在遍历中满足条件的最后一个layer (layer 21)。
接着试着将layer31 的位置改一下使得测试点处于layer31 里面:
输出变成了:
最终的结果变成了layer31,从这里我们就可以知道为什么不存在简单的短路设置(如果当前图层的位置的大小不满足条件就不遍历其子图层)了,因为子图层的位置与父图层并不存在直接关系,一个不在父图层中的点仍可能在其子图层中。
让我们再来把layer3 的maskToBounds 设为 YES:
再跑一遍,输出又变了:
我们可以看到当开启maskToBounds 之后,便开始有短路了,layer31 不再出现在遍历树里面。