在for循环中更改CAShapeLayer的路径不起作用

时间:2016-10-13 20:24:12

标签: ios objective-c animation cashapelayer cgpath

我正在for循环中更改 CAShapeLayer 的路径,但它只显示循环的最后结果。我知道,我可以用 CABasicAnimation 来做到这一点,但我需要以这种方式改变路径。任何想法如何做到这一点?

UIBezierPath *path = [ShapeManager getCirclePathAppendedWithCirclePathWithRadius:radius
                                                                        andFrame:self.view.bounds];
self.layer.fillRule = kCAFillRuleEvenOdd;
self.layer.fillColor = [UIColor grayColor].CGColor;
self.layer.opacity = 0.5;
self.layer.path = path.CGPath;
[self.view.layer addSublayer:self.layer];
for (int i = 1; i < 100; ++i) {
    path = [ShapeManager getCirclePathAppendedWithCirclePathWithRadius:self.view.bounds.size.width-i
                                                              andFrame:self.view.bounds];
    self.layer.path = path.CGPath;
}

辅助方法

+ (UIBezierPath *)getCirclePathAppendedWithCirclePathWithRadius:(CGFloat)radius andFrame:(CGRect)frame {
    UIBezierPath *backgroundPath = [UIBezierPath bezierPathWithRect:frame];
    [backgroundPath appendPath:[self getCirclePathWithRadius:radius andFrame:frame]];
    return backgroundPath;
}

+ (UIBezierPath *)getCirclePathWithRadius:(CGFloat)radius andFrame:(CGRect)frame {
    CGRect rect = frame;
    UIBezierPath *circlePath;
    circlePath = [UIBezierPath bezierPathWithArcCenter:(CGPoint){rect.size.width/2, rect.size.height/2} radius:radius startAngle:0 endAngle:M_PI*2 clockwise:YES];
    return circlePath;
}

1 个答案:

答案 0 :(得分:1)

您正确使用CABasicAnimation。

  1. 删除for循环,它不会完成任务。
  2. CABasicAnimation键添加path,并在其间进行插值。此代码只能在viewDidLoad方法中调用一次:
  3. UIBezierPath *fromPath = [self.class getCirclePathAppendedWithCirclePathWithRadius:self.view.bounds.size.width andFrame:self.view.bounds];
    UIBezierPath *toPath = [self.class getCirclePathAppendedWithCirclePathWithRadius:self.view.bounds.size.width-99 andFrame:self.view.bounds];
    
    CABasicAnimation * animation = [CABasicAnimation animationWithKeyPath:@"path"];
    animation.fromValue = (id)fromPath.CGPath;
    animation.toValue = (id)toPath.CGPath;
    animation.duration = 1; 
    
    [layer addAnimation:animation forKey:@"pathAnimation"];
    layer.speed = 0;
    

    <强>更新

    1. 在最后一行中,您将speed值设置为0,因为您将手动设置动画进度:
    2. @property (nonatomic, assign) double progress;
      
      - (void) setProgress: (double) progress {
          _progress = progress;        
          layer.timeOffset = (CFTimeInterval)progress; 
      }
      

      这假定动画持续时间为1.0。否则你需要设置

      layer.timeOffset = (CFTimeInterval)(progress * totalDuration);
      

      现在只需根据更新的值设置动作回调的进度。