Dou*_*ith 5 core-animation objective-c uiview cabasicanimation ios
示例项目: http ://cl.ly/1W3V3b0D2001
我正在使用CABasicAnimation创建一个像饼图一样的进度指示器.与iOS 7 app下载动画类似:

动画设置如下:
- (void)drawRect:(CGRect)rect
{
[super drawRect:rect];
CGFloat radius = CGRectGetWidth(self.frame) / 2;
CGFloat inset = 1;
CAShapeLayer *ring = [CAShapeLayer layer];
ring.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, inset, inset)
cornerRadius:radius-inset].CGPath;
ring.fillColor = [UIColor clearColor].CGColor;
ring.strokeColor = [UIColor whiteColor].CGColor;
ring.lineWidth = 2;
self.innerPie = [CAShapeLayer layer];
inset = radius/2;
self.innerPie.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, inset, inset)
cornerRadius:radius-inset].CGPath;
self.innerPie.fillColor = [UIColor clearColor].CGColor;
self.innerPie.strokeColor = [UIColor whiteColor].CGColor;
self.innerPie.lineWidth = (radius-inset)*2;
self.innerPie.strokeStart = 0;
self.innerPie.strokeEnd = 0;
[self.layer addSublayer:ring];
[self.layer addSublayer:self.innerPie];
self.progress = 0.0;
}
Run Code Online (Sandbox Code Playgroud)
通过设置视图的进度来触发动画:
- (void)setProgress:(CGFloat)progress animated:(BOOL)animated {
self.progress = progress;
if (animated) {
CGFloat totalDurationForFullCircleAnimation = 0.25;
CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
self.innerPie.strokeEnd = progress;
pathAnimation.delegate = self;
pathAnimation.fromValue = @([self.innerPie.presentationLayer strokeEnd]);
pathAnimation.toValue = @(progress);
pathAnimation.duration = totalDurationForFullCircleAnimation * ([pathAnimation.toValue floatValue] - [pathAnimation.fromValue floatValue]);
[self.innerPie addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
}
else {
[CATransaction setDisableActions:YES];
[CATransaction begin];
self.innerPie.strokeEnd = progress;
[CATransaction commit];
}
}
Run Code Online (Sandbox Code Playgroud)
但是,在我将进度设置为较小的情况下,例如0.25,动画中有一个跳跃.顺时针方向前进一点,向后跳,然后像往常一样继续往前走.如果将持续时间或进度设置得更高,则不会发生这种情况.
我怎么停止跳?除非进度非常低,否则此代码适用于所有情况.我究竟做错了什么?
啊! 我们应该早点看到这个.问题是你的if (animated)块中的这一行:
self.innerPie.strokeEnd = progress;
Run Code Online (Sandbox Code Playgroud)
由于innerPie是核心动画层,因此会导致隐式动画(大多数属性更改都会执行).这个动画与你自己的动画作斗争.您可以通过在设置strokeEnd时禁用隐式动画来防止这种情况发生:
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.innerPie.strokeEnd = progress;
[CATransaction commit];
Run Code Online (Sandbox Code Playgroud)
(注意如何setDisableActions:在begin/commit中.)
或者,您可以删除自己的动画,只需使用自动动画,使用类似的方法setAnimationDuration:来改变它的长度.
原始建议:
我的猜测是你drawRect:被调用,它会重置你的strokeEnd值.drawRect:无论如何都不应该设置这些层.尝试将该设置移动到init方法didMoveToWindow:或类似方法.
如果这不是有效的,我会建议增加日志报表跟踪的价值progress和[self.innerPie.presentationLayer strokeEnd]每一个方法被调用时,也许他们没有做你期望的事.
| 归档时间: |
|
| 查看次数: |
929 次 |
| 最近记录: |