【发布时间】:2013-11-21 21:51:27
【问题描述】:
我有一个项目,我正在根据设定的进度为 UIBezierPath 设置动画。 BezierPath 是圆形的,位于 UIView 中,动画现在使用 CADisplayLink 在 drawRect 中完成。简单地说,基于设定的进度x,路径应该径向扩展(如果x 比以前大)或收缩(如果x 更小)。
self.drawProgress = (self.displayLink.timestamp - self.startTime)/DURATION;
CGFloat startAngle = -(float)M_PI_2;
CGFloat stopAngle = ((self.x * 2*(float)M_PI) + startAngle);
CGFloat currentEndAngle = ((self.oldX * 2*(float)M_PI) + startAngle);
CGFloat endAngle = currentEndAngle-((currentEndAngle-stopAngle)*drawProgress);
UIBezierPath *guideCirclePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
这是x 自我们上次更新以来缩小的情况。我遇到的问题实际上有几个:
- 形状总是从 45º 开始绘制(除非我旋转视图)。我还没有找到任何方法来改变它,将
startAngle设置为 -45º 并没有什么区别,因为它总是“弹出”为 45。对此我有什么办法吗,还是我必须求助于其他方法画画? - 还有其他方法可以让这些东西动起来吗?我已经阅读了很多关于使用
CAShapeLayer的内容,但我还不太了解使用这两种方法的实际区别(就缺点和好处而言)。如果有人能澄清一下,我将非常感激!
更新:我将代码迁移到 CAShapeLayer,但现在我面临一个不同的问题。最好用这张图来描述:
发生的情况是,当层应该收缩时,细外线仍然存在(无论移动方向如何)。当条形缩小时,除非我明确地在其上创建一个新的白色形状,否则 1-x 的增量不会被删除。代码如下。有什么想法吗?
UIBezierPath *circlePath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:startAngle endAngle:stopAngle clockwise:YES];
CAShapeLayer *circle = [CAShapeLayer layer];
circle.path = [circlePath CGPath];
circle.strokeStart = 0;
circle.strokeEnd = 1.0*self.progress;
// Colour and other customizations here.
if (self.progress > self.oldProgress) {
drawAnimation.fromValue = @(1.0*self.oldProgress);
drawAnimation.toValue = @(circle.strokeEnd);
} else {
drawAnimation.fromValue = @(1.0*self.oldProgress);
drawAnimation.toValue = @(1.0*self.progress);
circle.strokeEnd = 1.0*self.progress;
}
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; //kCAMediaTimingFunctionEaseIn
[circle addAnimation:drawAnimation forKey:@"strokeEnd"];
更新 2:我已经解决了大部分其他错误。原来只是我一直很傻,把整个动画过度复杂化(更不用说到处乘以 1,什么?)。我制作了一个我无法解决的错误的 gif 图像:
有什么想法吗?
更新 3:(和关闭)。我设法通过调用摆脱了这个错误
[self.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
现在一切正常。感谢大家的帮助!
【问题讨论】:
-
我已经迁移到使用 CAShapeLayer+CABasicAnimation 因为似乎有更合理的选择,部分原因是能够使用邓肯推荐的属性。
-
在 Swift 中寻找一个好的解决方案。
标签: ios objective-c core-animation uibezierpath cadisplaylink