如何使用CAKeyframeAnimation对形状的CoreGraphics图形进行动画处理 [英] How to Animate CoreGraphics Drawing of Shape Using CAKeyframeAnimation

查看:119
本文介绍了如何使用CAKeyframeAnimation对形状的CoreGraphics图形进行动画处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对UIView子类中的UIBeizerPath(在我的示例中为三角形)的图形进行动画处理。但是,整个子视图是动画而不是形状。

I am trying to animate the drawing of a UIBeizerPath (in my example a triangle) in a UIView subclass. However, the entire subview is animating instead of the shape.

动画是否缺少某些内容?

Is there something I am missing with the animation?

- (void)drawRect:(CGRect)rect {

   CAShapeLayer *drawLayer = [CAShapeLayer layer];

   drawLayer.frame           = CGRectMake(0, 0, 100, 100);
   drawLayer.strokeColor     = [UIColor greenColor].CGColor;
   drawLayer.lineWidth       = 4.0;

   [self.layer addSublayer:drawLayer];

   UIBezierPath *path = [UIBezierPath bezierPath];

  [path moveToPoint:CGPointMake(0,0)];
  [path addLineToPoint:CGPointMake(50,100)];
  [path addLineToPoint:CGPointMake(100,0)];
  [path closePath];

  CGPoint center = [self convertPoint:self.center fromView:nil];

  [path applyTransform:CGAffineTransformMakeTranslation(center.x, center.y)];

  [[UIColor redColor] set];

  [path fill];

  [[UIColor blueColor] setStroke];

  path.lineWidth = 3.0f;

  [path stroke];

  CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

  pathAnimation.duration        = 4.0f;
  pathAnimation.path            = path.CGPath;
  pathAnimation.calculationMode = kCAAnimationLinear;

  [drawLayer addAnimation:pathAnimation forKey:@"position"];
}


推荐答案


  • 您正在创建 CAShapeLayer ,但是随后并没有做任何有用的事情。我们来解决这个问题。

    • You are creating a CAShapeLayer, but then not doing anything useful with it. Let's fix that.

      不要在 -drawRect:中设置图层和动画,因为那是严格来说,这是使用CoreGraphics或UIKit API进行绘图的时间。相反,您希望CAShapeLayer绘制三角形-这样就可以对其进行动画处理。

      Don't set up layers and animations in -drawRect:, because that's strictly meant as a time to do drawing using the CoreGraphics or UIKit APIs. Instead, you want the CAShapeLayer to draw the triangle -- that way you can animate it.

      CAKeyframeAnimation.path用于完全不同的事物(例如,沿路径移动图层)。

      CAKeyframeAnimation.path is meant for something completely different (e.g. moving a layer along a path).

      您的动画正在为图层的位置值设置动画。毫不奇怪,它可以移动图层!您想改为对路径值进行动画处理。

      Your animation is animating the position value of the layer. No surprise that it moves the layer! You want to animate the path value instead.

      CAKeyframeAnimation背后的思想是为您提供一个 values 数组将图层的属性设置为。在关键帧之间的时间间隔内,它将在两个相邻关键帧之间进行插值。因此,您需要给它提供几种路径-每侧一条。

      The idea behind CAKeyframeAnimation is that you provide it an array of values to set the layer's property to. During the time between keyframes, it will interpolate between the two adjacent keyframes. So you need to give it several paths -- one for each side.

      很难插值任意路径。当路径具有相同数量和相同种类的元素时,CA的路径插值效果最佳。因此,我们确保所有路径都具有相同的结构,只是在某些点之间彼此重叠。

      Interpolating arbitrary paths is difficult. CA's path interpolation works best when the paths have the same same number and kind of elements. So, we make sure all our paths have the same structure, just with some points on top of each other.

      动画甚至计算机的秘密通常,您必须准确地解释您想发生的事情。 我想为每个点的动画设置动画,因此看起来好像很生动,信息还远远不够。

      The secret to animation, and maybe to computers in general: you must be precise in explaining what you want to happen. "I want to animate the drawing of each point, so it appears to be animated" is not nearly enough information.

      这里是一个UIView子类,我认为可以满足您的要求,或者至少可以关闭。要设置动画,请在 -animate:动作上附加一个按钮。

      Here's a UIView subclass that I think does what you're asking for, or at least close. To animate, hook a button up to the -animate: action.

      SPAnimatedShapeView.h:

      SPAnimatedShapeView.h:

      #import <UIKit/UIKit.h>
      
      @interface SPAnimatedShapeView : UIView
      
      - (IBAction)animate:(id)sender;
      
      @end
      

      SPAnimatedShapeView.m:

      SPAnimatedShapeView.m:

      #import "SPAnimatedShapeView.h"
      #import <QuartzCore/QuartzCore.h>
      
      @interface SPAnimatedShapeView ()
      @property (nonatomic, retain)   CAShapeLayer*   shapeLayer;
      @end
      
      @implementation SPAnimatedShapeView
      
      @synthesize shapeLayer = _shapeLayer;
      
      - (void)dealloc
      {
          [_shapeLayer release];
          [super dealloc];
      }
      
      - (void)layoutSubviews
      {
          if (!self.shapeLayer)
          {
              self.shapeLayer = [[[CAShapeLayer alloc] init] autorelease];
              self.shapeLayer.bounds = CGRectMake(0, 0, 100, 100);     // layer is 100x100 in size
              self.shapeLayer.position = self.center;                  // and is centered in the view
              self.shapeLayer.strokeColor = [UIColor blueColor].CGColor;
              self.shapeLayer.fillColor = [UIColor redColor].CGColor;
              self.shapeLayer.lineWidth = 3.f;
      
              [self.layer addSublayer:self.shapeLayer];
          }
      }
      
      - (IBAction)animate:(id)sender
      {
          UIBezierPath* path0 = [UIBezierPath bezierPath];
          [path0 moveToPoint:CGPointZero];
          [path0 addLineToPoint:CGPointZero];
          [path0 addLineToPoint:CGPointZero];
          [path0 addLineToPoint:CGPointZero];
      
          UIBezierPath* path1 = [UIBezierPath bezierPath];
          [path1 moveToPoint:CGPointZero];
          [path1 addLineToPoint:CGPointMake(50,100)];
          [path1 addLineToPoint:CGPointMake(50,100)];
          [path1 addLineToPoint:CGPointMake(50,100)];
      
          UIBezierPath* path2 = [UIBezierPath bezierPath];
          [path2 moveToPoint:CGPointZero];
          [path2 addLineToPoint:CGPointMake(50,100)];
          [path2 addLineToPoint:CGPointMake(100,0)];
          [path2 addLineToPoint:CGPointMake(100,0)];
      
          UIBezierPath* path3 = [UIBezierPath bezierPath];
          [path3 moveToPoint:CGPointZero];
          [path3 addLineToPoint:CGPointMake(50,100)];
          [path3 addLineToPoint:CGPointMake(100,0)];
          [path3 addLineToPoint:CGPointZero];
      
          CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"path"];    
          animation.duration = 4.0f;
          animation.values = [NSArray arrayWithObjects:(id)path0.CGPath, (id)path1.CGPath, (id)path2.CGPath, (id)path3.CGPath, nil];
          [self.shapeLayer addAnimation:animation forKey:nil];
      }
      
      @end
      

      这篇关于如何使用CAKeyframeAnimation对形状的CoreGraphics图形进行动画处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆