我可以在表示层中访问 CAShapeLayer 的路径 属性 吗?

Can I access a CAShapeLayer's path property in the presentation layer?

我有一个名为 "starfish" 的 UIView 子视图。它的底层是一个 CAShapeLayer,它的路径描边是一个海星的形状。我想在封闭路径内的视图控制器中对这个形状进行命中测试,而不是视图的矩形。这没问题,我只是在我的视图控制器的 touchesBegan 中的 CAShapeLayer 路径 属性 上调用 CGPathContainsPoint() 并命中测试工作。

CGPoint p = [[touches anyObject] locationInView:self.view];
CGPoint q = [self.view convertPoint:p toView:self.starfish];

if (CGPathContainsPoint([(CAShapeLayer*)self.starfish.layer path], NULL, q, true))
    NSLog(@"Success");
else
    NSLog(@"Fail");

如果视图是动画的,从 A 移动到 B,则相同的命中测试将需要访问表示层中的 CAShapeLayer 路径,但我似乎无法访问它。

// Not working during animation
if (CGPathContainsPoint([(CAShapeLayer*)self.starfish.layer.presentationLayer path], NULL, q, true))
    NSLog(@"Success");
else
    NSLog(@"Fail");

好吧,我找到了一个有效的解决方案。我创建了一个新的 CAShapeLayer,其路径和框架(基于表示层)与我在 touchesBegan 中测试的 CAShapelayer 相同。

CGPoint p = [[touches anyObject] locationInView:self.view];

CGRect rect = [(CAShapeLayer*)self.starfish.layer.presentationLayer frame];

CAShapeLayer *shape = [CAShapeLayer layer];
shape.path = [(CAShapeLayer*)self.starfish.layer path];
shape.frame = rect;

CGPoint q = [self.view.layer convertPoint:p toLayer:shape];

if (CGPathContainsPoint(shape.path, NULL, q, true))
    NSLog(@"Success");
else
    NSLog(@"Fail");

您无法访问路径 属性 的原因是因为 layer.presentationLayerCALayer 的 属性 并且它本身是 CALayer 类型,不是 CAShapeLayer。但是,如果层是 CAShapeLayer 类型,根据我的经验,layer.presentationLayerCAShapeLayer 是安全的,之后您可以访问路径 属性.