ios_core_animation_advanced_techniques
ios_core_animation_advanced_techniques copied to clipboard
Chapter 3.1 Hit Testing 中 关于 hitTest 与 zPosition的论述经过测试有误
注意当调用图层的-hitTest:方法时,测算的顺序严格依赖于图层树当中的图层顺序(和UIView处理事件类似)。之前提到的zPosition属性可以明显改变屏幕上图层的顺序,但不能改变事件传递的顺序。 这意味着如果改变了图层的z轴顺序,你会发现将不能够检测到最前方的视图点击事件,这是因为被另一个图层遮盖住了,虽然它的zPosition值较小,但是在图层树中的顺序靠前。我们将在第五章详细讨论这个问题。
论述说 改变zPosition值不会改变 hitTest:
方法的返回值,但是经过如下示例代码测试,发现改变zPosition值会改变 hitTest:
方法的返回值。
示例代码:
- (void)addSomeLayers{
self.tempLayer = [CALayer layer];
self.tempLayer.backgroundColor = [UIColor blueColor].CGColor;
self.tempLayer.frame = CGRectMake(100, 100, 200, 200);
[self.view.layer addSublayer:self.tempLayer];
self.redLayer = [CALayer layer];
self.redLayer.backgroundColor = [UIColor redColor].CGColor;
self.redLayer.frame = CGRectMake(50, 50, 50, 50);
[self.tempLayer addSublayer:self.redLayer];
self.yellowLayer = [CALayer layer];
self.yellowLayer.backgroundColor = [UIColor yellowColor].CGColor;
self.yellowLayer.frame = CGRectMake(75, 75, 100, 100);
[self.tempLayer addSublayer:self.yellowLayer];
self.redLayer.zPosition = 1;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *anyTouch = [touches anyObject];
CGPoint point = [anyTouch locationInView:self.view];
CALayer *layer = [self.view.layer hitTest:point];
if (layer == self.tempLayer) {
NSLog(@"touch blue layer");
}
else if (layer == self.view.layer){
NSLog(@"touch self.view.layer");
}
else if(layer == self.redLayer){
NSLog(@"touch red layer");
}
else if(layer == self.yellowLayer){
NSLog(@"touch yellow layer");
}
}
在self.tempLayer
上先后添加了self.redLayer
和self.yellowLayer
,图层树中的顺序应该是self.yellowLayer
在最上面,但是通过self.redLayer.zPosition = 1;
改变self.redLayer
的显示顺序后,hitTest:
方法返回了self.redLayer
对哦,我那天也是过一次,发现是返回最上面的图层,我以为是iOS 10新版本更改了这个特性。