【问题标题】:iOS: CAShapeLayer, CALayer mask, hitTest:WithEvents, hitTest:iOS:CAShapeLayer、CALayer 掩码、hitTest:WithEvents、hitTest:
【发布时间】:2013-06-17 23:13:04
【问题描述】:

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

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: 吗?我已经尝试过了,但它被调用了三遍。返回的点是正确的,但我希望找到一种方法来了解是否从容器视图中触摸了动画视图。换句话说,我想知道 subView /subLayer 是否被触摸。

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

UIViewController 初始化UIView 类并将其添加为子视图。 在这个UIView 类中,其层被CALayer * layer = (CALayer *) self.layer 设置为CALayerCAShapeLayer 被设置为CALayer 的掩码,并且动画在形状层的路径上设置。

而且我希望能够在UIViewController 中触摸图层

是否可以从将其添加为子视图的UIViewController 的图层设置为CALayer 的视图中由 CAShapeLayer 动画的图层获取触摸点?请举例说明。

提前非常感谢。问候。

【问题讨论】:

    标签: ios calayer hittest cashapelayer


    【解决方案1】:

    我认为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 属性在动画期间更新,它也不会说明任何内容。

    【讨论】:

      【解决方案2】:

      试试这样的:

      - (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 并将其转换回真实图层。这将使它与动画一起工作。

      我希望这对你有用。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多