动画圆形UIBezierPath

时间:2013-11-21 21:51:28

标签: ios objective-c core-animation uibezierpath cadisplaylink

我有一个项目,我根据设定的进度动画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缩小了这种情况。我遇到的问题实际上是一些问题:

  1. 形状始终开始以45º绘制(除非我旋转视图)。我没有找到任何方法来改变这一点,将startAngle设置为-45º并没有什么区别,因为它总是“弹出”到45。我有什么可以做的,或者我必须求助于其他绘图方法?
  2. 还有其他任何方式可以为这些东西制作动画吗?我已经阅读了很多关于使用CAShapeLayer的内容,但我还没有完全理解使用这两种方法的实际差异(在缺点和好处方面)。如果有人能澄清我会非常有责任!
  3. 更新:我将代码迁移到CAShapeLayer,但现在我面临着另一个问题。最好用这张图片描述:

    enter image description here

    正在发生的事情是,当该层应该收缩时,薄外线仍然存在(无论移动方向如何)。当条形收缩时,除非我明确地在其上形成新的白色形状,否则不会移除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,什么?)。我做了一个我无法解决的bug的gif:

    radial control glitch

    有什么想法吗?

    更新3:(和关闭)。我设法通过调用

    来摆脱这个错误
    [self.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
    

    现在一切正常。谢谢你的帮助!

1 个答案:

答案 0 :(得分:11)

使用CAShapeLayer更容易,更清洁。原因是CAShapeLayer包含属性strokeStart和strokeEnd。这些值的范围从0(路径的开头)到1(路径的结尾)并且是可动画的。

通过更改它们,您可以轻松绘制圆圈的任何圆弧(或任意路径的任何部分,就此而言。)属性是可动画的,因此您可以创建一个增长/缩小的饼图切片或部分的动画。一个环形。它比在drawRect中实现代码更容易,更高效。