在 for 循环中更改 CAShapeLayer 的路径无效
Changing CAShapeLayer's path in for loop makes no effect
我正在改变 CAShapeLayer 在 for
循环中的路径,但它只显示循环的最后结果。我知道,我可以用 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;
}
您关于使用 CABasicAnimation 的看法是正确的。
- 删除你的
for
循环,它不会完成这项工作。
- 为
path
键添加 CABasicAnimation
,并在其中插入值。此代码只应在 viewDidLoad
方法中调用一次:
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;
更新:
- 在最后一行中,您将
speed
值设置为 0,因为您将手动设置动画进度:
@property (nonatomic, assign) double progress;
- (void) setProgress: (double) progress {
_progress = progress;
layer.timeOffset = (CFTimeInterval)progress;
}
这假定动画持续时间为 1.0。否则你需要设置
layer.timeOffset = (CFTimeInterval)(progress * totalDuration);
现在根据更新后的值在运动回调中设置进度即可。
我正在改变 CAShapeLayer 在 for
循环中的路径,但它只显示循环的最后结果。我知道,我可以用 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;
}
您关于使用 CABasicAnimation 的看法是正确的。
- 删除你的
for
循环,它不会完成这项工作。 - 为
path
键添加CABasicAnimation
,并在其中插入值。此代码只应在viewDidLoad
方法中调用一次:
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;
更新:
- 在最后一行中,您将
speed
值设置为 0,因为您将手动设置动画进度:
@property (nonatomic, assign) double progress;
- (void) setProgress: (double) progress {
_progress = progress;
layer.timeOffset = (CFTimeInterval)progress;
}
这假定动画持续时间为 1.0。否则你需要设置
layer.timeOffset = (CFTimeInterval)(progress * totalDuration);
现在根据更新后的值在运动回调中设置进度即可。