[英]iOS: CAShapeLayer, CALayer mask, hitTest:WithEvents, hitTest:
Thanks in advance: I have a view hierarchy like this: 在此先感谢:我有一个这样的视图层次结构:
A UIView
within this I set: CALayer * layer = (CALayer*) self.layer
我在其中设置的UIView
: CALayer * layer = (CALayer*) self.layer
And within this class I have a CAShapeLayer
, which is set as the mask of the CALayer
. 在这个类中,我有一个CAShapeLayer
,它被设置为CALayer
的掩码。
It animates fine, no problem. 它动画效果很好,没问题。
I have a UIViewController
that init the above UIView
by: 我有一个UIViewController
通过以下方式初始化上面的UIView
:
myView = [myAnimationView alloc] initWithFrame:(CGRect){{0, 0}, 320, 450}]; [self.view addSubview myView];
So what I have is: a UIView
class and the above UIViewController
class. 所以我所拥有的是:一个UIView
类和上面的UIViewController
类。 Nothing else. 没有其他的。
As the CAShapeLayer
animates (it is only a basic ca animation, scaling from a small circle to a larger one), I hope to be able to get the touch point within UIViewController
that inits this UIView
随着CAShapeLayer
动画化(这只是一个基本的ca动画,从一个小圆圈缩放到一个较大的圆圈),我希望能够在初始化该UIView
UIViewController
中获得接触点
Should I use hitTest:WithEvents: here? 我应该在这里使用hitTest:WithEvents:吗? I have tried it, but it get called three times. 我已经尝试过了,但是却被调用了三遍。 The returned points are correct, but I was hoping to find a way to know whether or not an animated view is being touched from the container view. 返回的点是正确的,但是我希望找到一种方法来知道是否从容器视图中触摸了动画视图。 Other words, I would like to know if the subView /subLayer is being touched. 换句话说,我想知道subView / subLayer是否被触摸。
In summary, here is my view hierarchy: 总而言之,这是我的视图层次结构:
UIViewController
initializes the UIView
class and adds it as subView. UIViewController
初始化UIView
类,并将其添加为subView。 Within this UIView
class its layer is set to be CALayer
by CALayer * layer = (CALayer *) self.layer
and the CAShapeLayer
is set to be the mask of the CALayer
and animation is set on the shape layer's path. 在此UIView
类中,通过CALayer * layer = (CALayer *) self.layer
将其图层设置为CALayer
,并将CAShapeLayer
设置为CALayer
的蒙版,并在形状图层的路径上设置动画。
And I would like to to able to get the layer touched within UIViewController
我希望能够在UIViewController
接触到该层
Is it possible to get the touch point from a layer that is being animated by CAShapeLayer within a view whose layer is set to be CALayer
from a UIViewController
that adds it as its subview? 是否可以从将视图设置为CALayer
的视图中,将由CAShapeLayer动画化的层中的接触点从UIViewController
添加到其子视图中? Please cite with examples. 请举一些例子。
Thanks very much in advance. 首先十分感谢。 Regards. 问候。
I think CALayer
isn't designed to receive/handle touch events (which is one big difference to UIView
). 我认为CALayer
并非旨在接收/处理触摸事件(这与UIView
有很大的不同)。 I tested for a (long press) touch within a CAShapeLayer.path
from the ViewController with something like 我测试了ViewController在CAShapeLayer.path
的(长按)触摸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);
}
There's one caveat however: my path isn't animated. 但是有一个警告:我的路径没有动画。 In the docs for CAShapeLayer it also doesn't say anything if the CAShapeLayer.path
property updates during the animation. 在CAShapeLayer的文档中,如果CAShapeLayer.path
属性在动画过程中进行了更新,它也不会说什么。
Try something like this: 尝试这样的事情:
- (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
}
}
You will have to setup your TapGestureRecognizer, I did this using Interface Builder but you can do it in code if you want. 您将必须设置TapGestureRecognizer,我使用Interface Builder进行了此设置,但是您可以根据需要在代码中进行设置。 Be sure that your layers have proper bounds setup, and you also need to set the bounds on your mask. 确保您的图层具有正确的边界设置,并且还需要在蒙版上设置边界。
Notice that I am getting the presentationLayer and the converting it back to the real layer. 注意,我正在获取presentationLayer,并将其转换回真实图层。 This will cause it to work with animations. 这将使其与动画一起使用。
I hope this works for you. 希望这对您有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.