【问题标题】:Animate CAShapeLayer setPath动画 CAShapeLayer 设置路径
【发布时间】:2016-06-05 20:09:05
【问题描述】:

我正在尝试在绘制 bezierPath 时添加动画。有基圆深灰色(0 到 360)、绿色路径(-90 到 0)和红色路径(0 到 90)。

#import "ProgressBar.h"



@interface ProgressBar ()
{
    CAShapeLayer *lightGrayPath;
}



@end

@implementation ProgressBar

-(id)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if(self){
        [self initValues];
    }
    return self;
}

-(id) initWithCoder:(NSCoder *)aDecoder{
    self = [super initWithCoder:aDecoder];
    if(self){
        [self initValues];
    }
    return self;
}
-(void)awakeFromNib{
    [super awakeFromNib];
    [self startAnimation];

}


-(void)initValues{
    lightGrayPath = [CAShapeLayer layer];
    lightGrayPath.fillColor = [UIColor clearColor].CGColor;
    lightGrayPath.lineWidth=2.0f;
    lightGrayPath.strokeColor =[UIColor colorWithWhite:0 alpha:0.1].CGColor;
    [self.layer addSublayer:lightGrayPath];
}


-(void)startAnimation{
    CGRect rect=self.bounds;
    CGFloat subPathWidth=10.0;
    UIBezierPath *bezierPath_lightGray=[UIBezierPath bezierPath];
    bezierPath_lightGray.lineWidth=lightGrayPath.lineWidth;

    [bezierPath_lightGray addArcWithCenter:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)) radius:(rect.size.height / 2)- subPathWidth/2.0
                                startAngle:0 endAngle:2*M_PI clockwise:YES];









    UIBezierPath *bezierPath_green=[UIBezierPath bezierPath];
    bezierPath_green.lineWidth=subPathWidth;

    [[UIColor greenColor] setStroke];
    [bezierPath_green addArcWithCenter:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)) radius:(rect.size.height / 2)- subPathWidth/2.0 startAngle:-M_PI/2.0     endAngle:0 clockwise:YES];
    [bezierPath_green stroke];
    [bezierPath_lightGray appendPath:bezierPath_green];


    UIBezierPath *bezierPath_red=[UIBezierPath bezierPath];
    bezierPath_red.lineWidth=subPathWidth;


    [[UIColor redColor] setStroke];
    [bezierPath_red addArcWithCenter:CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)) radius:(rect.size.height / 2)- subPathWidth/2.0 startAngle:0     endAngle:M_PI_2 clockwise:YES];
    [bezierPath_red stroke];
    [bezierPath_lightGray appendPath:bezierPath_red];


    lightGrayPath.path=bezierPath_lightGray.CGPath;


    //    CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
    //    pathAnimation.duration = 10.0;
    //    //pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
    //    pathAnimation.toValue = [NSNumber numberWithFloat:1.0f];
    //    [lightGrayPath addAnimation:pathAnimation forKey:@"path"];
}



@end

我想显示正在绘制的路径的动画。 lightGrayArc 应该没有动画效果。绿色弧线和红色弧线应该是。

但是,由于我只使用一个 CAShapeLayer 并为其附加路径。当我使用动画时,它会为浅灰色路径设置动画,绿色和红色弧没有动画。

【问题讨论】:

  • 顺便说一句,在处理CAShapeLayer 时,您不应该在drawRect 中做任何事情。您通常会在 awakeFromNIB 或初始化方法中执行此操作。
  • @Rob True,我使用它只是为了澄清目的。
  • 好的,但它根本没有澄清它。它只会使问题更加模糊。永远不要从drawRect 启动动画。 drawRect 的目的是绘制单帧。我还不清楚绿色和蓝色弧线的所需动画。同时地?一个接一个?

标签: ios cashapelayer cabasicanimation


【解决方案1】:

我建议:

  1. 不要在drawRect 中设置动画。那是用来画单帧的。

  2. 有两种方法可以为路径设置动画:

    • 根本不使用CAShapeLayer,而是定义一个drawRect,它对一个或多个UIBezierPath执行stroke

      要制作动画,不要使用CABasicAnimation,而是使用CADisplayLink(一种针对屏幕更新优化的计时器)更改一些定义路径开始和结束位置的属性,然后调用setNeedsDisplay,这将触发对drawRect 的调用,该调用将使用这些属性来stroke 动画该帧的路径。

    • 更简单的是,根本不要使用drawRect 来抚摸任何东西。只需将灰色、绿色和红色弧添加为三个不同的 CAShapeLayer 实例。让CAShapeLayer 为您完成所有弧线的渲染。

      当您想要为红色和绿色图层设置动画时,请为相应的图层添加 CABasicAnimation

【讨论】:

  • 我确实想到了不同的 CAShapeLayer,但后来认为这将是一个内存昂贵的操作。因此,计划使用一个 CAShapeLayer 并向其添加路径,它会像第一个绿色路径一样进行动画处理,然后一旦它即将结束,它应该开始红色路径,一旦达到红色,停止任何动画。
  • 三个形状层的内存影响是无关紧要的,而且制作所需的动画要容易得多。如果您想采用drawRect 方法,您将完全退休CAShapeLayer,并使用CADisplayLink 制作动画。但恕我直言,这不值得麻烦。
猜你喜欢
  • 1970-01-01
  • 2019-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多