iOS:CAShapeLayer,CALayer mask,hitTest:WithEvents,hitTest:

时间:2013-06-17 23:13:04

标签: ios calayer hittest cashapelayer

提前致谢:我有一个像这样的视图层次结构:

A UIView 在此我设置:CALayer * layer = (CALayer*) self.layer

在这个课程中我有一个CAShapeLayer,它被设置为CALayer的掩码。

它动画很好,没问题。

我有UIViewController通过以下方式启动上述UIView

myView = [myAnimationView alloc] initWithFrame:(CGRect){{0, 0}, 320, 450}]; [self.view addSubview myView];

所以我拥有的是:UIView类和上面的UIViewController类。没有其他的。

由于CAShapeLayer动画(它只是一个基本的ca动画,从一个小圆圈缩放到一个较大的圆圈),我希望能够获得UIViewController内的触摸点。 UIView

我应该使用hitTest:WithEvents:here?我试过了,但它被调用了三次。返回的点是正确的,但我希望找到一种方法来了解是否从容器视图中触摸了动画视图。换句话说,我想知道是否触摸了subView / subLayer。

总之,这是我的视图层次结构:

UIViewController初始化UIView类并将其添加为subView。 在此UIView类中,其图层由CALayer设置为CALayer * layer = (CALayer *) self.layerCAShapeLayer设置为CALayer的掩码,动画设置为形状层的路径。

我希望能够在UIViewController

中触及图层

是否有可能从CASepeLayer动画的图层中获取触摸点,该图层的图层的图层设置为CALayer,而UIViewController将其添加为子视图?请举例说明。

非常感谢提前。问候。

2 个答案:

答案 0 :(得分:0)

我认为CALayer并非设计用于接收/处理触摸事件(这与UIView有很大不同)。 我在ViewController的CAShapeLayer.path内测试了一个(长按)触摸,类似于

- (void)handleLongPress:(UILongPressGestureRecognizer *)recognizer {
    CGPoint currentPoint = [recognizer locationInView:self.overlayView];
    bool didSelect = [self selectPathContainingPoint:currentPoint];
    if (didSelect) {
        [self updateViews];
    }
}

- (BOOL)selectPathContainingPoint:(CGPoint)point {
    CALayer * layer = (CALayer *) self.layer;
    CAShapeLayer *mask = (CAShapeLayer *)layer.mask;
    return CGPathContainsPoint(mask.path, nil, point);
}

但有一点需要注意:我的路径没有动画。在CAShapeLayer的文档中,如果CAShapeLayer.path属性在动画期间更新,它也没有说什么。

答案 1 :(得分:0)

尝试这样的事情:

- (void)setup
{
    _maskLayer = [CAShapeLayer layer];
    _maskLayer.fillColor = [UIColor whiteColor].CGColor;
    _maskLayer.path = somePath;

    _theLayer.frame = CGRectMake(0, 0, size.width, size.height);

    // Apply a mask
    _maskLayer.frame = _theLayer.frame;
    _theLayer.mask = _maskLayer;
}

- (IBAction)tapOnView:(UITapGestureRecognizer *)sender
{
    CGPoint point = [sender locationInView:theView];
    CALayer *subLayer = [_theLayer.presentationLayer hitTest:point].modelLayer;

    if (subLayer != _theLayer && subLayer != nil) {
        // Do something with the sublayer which the user touched
    }
}

您必须设置TapGestureRecognizer,我是使用Interface Builder完成的,但您可以根据需要在代码中执行此操作。确保图层具有适当的边界设置,并且还需要在蒙版上设置边界。

请注意,我正在获取presentationLayer并将其转换回真实图层。这将使其与动画一起使用。

我希望这适合你。