Uiview 如何使用CAKeyframeAnimation为形状的CoreGraphics绘制动画

Uiview 如何使用CAKeyframeAnimation为形状的CoreGraphics绘制动画,uiview,core-animation,core-graphics,cakeyframeanimation,Uiview,Core Animation,Core Graphics,Cakeyframeanimation,我试图在UIView子类中为UIBeizerPath(在我的示例中为三角形)的绘图设置动画。但是,整个子视图正在设置动画,而不是形状 动画中有什么我遗漏的吗 - (void)drawRect:(CGRect)rect { CAShapeLayer *drawLayer = [CAShapeLayer layer]; drawLayer.frame = CGRectMake(0, 0, 100, 100); drawLayer.strokeColor

我试图在UIView子类中为UIBeizerPath(在我的示例中为三角形)的绘图设置动画。但是,整个子视图正在设置动画,而不是形状

动画中有什么我遗漏的吗

- (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
    ,但没有使用它做任何有用的事情。让我们来解决这个问题

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

  • CAKeyframeAnimation.path用于完全不同的对象(例如,沿路径移动层)

  • 您的动画正在设置层的
    位置
    值的动画。毫不奇怪,它会移动图层!您希望改为设置
    路径
    值的动画

  • CAKeyframeAnimation背后的思想是为其提供一个
    值数组
    ,以将层的特性设置为。在关键帧之间的时间内,它将在两个相邻关键帧之间插值。所以你需要给它几条路径——每边一条

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

  • 动画的秘密,也许对一般的计算机来说:你必须精确地解释你想要发生什么。“我想为每个点的图形设置动画,使其看起来像是动画”,这几乎是不够的信息

这里有一个UIView子类,我认为它能满足您的要求,或者至少很接近。要设置动画,请将按钮挂接到
-animate:
操作

SPAnimatedShapeView.h:

#import <UIKit/UIKit.h>

@interface SPAnimatedShapeView : UIView

- (IBAction)animate:(id)sender;

@end
#导入
@界面SPAnimatedShapeView:UIView
-(iAction)动画:(id)发送者;
@结束
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
#导入“SPAnimatedShapeView.h”
#进口
@接口SPAnimatedShapeView()
@属性(非原子,保留)CAShapeLayer*shapeLayer;
@结束
@实现SPAnimatedShapeView
@合成形状层=_形状层;
-(无效)解除锁定
{
[_ShapelayerRelease];
[super dealoc];
}
-(无效)布局子视图
{
如果(!self.shapeLayer)
{
self.shapeLayer=[[CAShapeLayer alloc]init]autorelease];
self.shapeLayer.bounds=CGRectMake(0,0,100,100);//层的大小为100x100
self.shapeLayer.position=self.center;//并且在视图中居中
self.shapeLayer.strokeColor=[UIColor blueColor].CGColor;
self.shapeLayer.fillColor=[UIColor redColor].CGColor;
self.shapeLayer.lineWidth=3.f;
[self.layer addSublayer:self.shapeLayer];
}
}
-(iAction)动画:(id)发送者
{
UIBezierPath*路径0=[UIBezierPath bezierPath];
[路径0移动点:CGPointZero];
[path0 addLineToPoint:CGPointZero];
[path0 addLineToPoint:CGPointZero];
[path0 addLineToPoint:CGPointZero];
UIBezierPath*路径1=[UIBezierPath bezierPath];
[path1 moveToPoint:CGPointZero];
[path1 addLineToPoint:CGPointMake(50100)];
[path1 addLineToPoint:CGPointMake(50100)];
[path1 addLineToPoint:CGPointMake(50100)];
UIBezierPath*路径2=[UIBezierPath bezierPath];
[path2 moveToPoint:CGPointZero];
[path2 addLineToPoint:CGPointMake(50100)];
[path2 addLineToPoint:CGPointMake(100,0)];
[path2 addLineToPoint:CGPointMake(100,0)];
UIBezierPath*path3=[UIBezierPath bezierPath];
[路径3移动点:CGPointZero];
[path3 addLineToPoint:CGPointMake(50100)];
[path3 addLineToPoint:CGPointMake(100,0)];
[path3 addLineToPoint:CGPointZero];
CAKeyframeAnimation*动画=[CAKeyframeAnimation animation WithKeyPath:@“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];
}
@结束

准确解释“为UIBezierPath绘制动画”的含义。你想让它一个接一个地画出各个部分,还是什么?@kurt是的,我想画出每个点的动画,使三角形看起来像动画一样。谢谢你的解释。这真的很有帮助。事实证明还有一种更简单的方法:使用
cabasicanition
从0到1设置
strokeEnd
属性的动画。