动画圆形UIBezierPath

hav*_*hav 17 core-animation objective-c ios cadisplaylink uibezierpath

我有一个项目,我根据设定的进度动画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];
Run Code Online (Sandbox Code Playgroud)

这是x自我们上次更新以来收缩的情况.我遇到的问题实际上是一些:

  1. 形状始终以45º开始绘制(除非我旋转视图).我还没有找到任何方法来改变这一点,设置startAngle为-45º没有任何区别,因为它总是"弹出"到45.我有什么可以做的,或者我是否必须采用其他绘图方法?
  2. 有什么其他方式可以让这些东西动起来吗?我已经阅读了很多关于使用的内容,CAShapeLayer但我还没有完全理解使用这两种方法的实际差异(在缺点和好处方面).如果有人能澄清我会非常感激!

更新:我将代码迁移到CAShapeLayer,但现在我面临着另一个问题.最好用这张图片描述:

在此输入图像描述

发生的事情是,当层应该收缩时,薄的外线仍然存在(无论移动方向如何).当棒收缩时,x除非我明确地在其上形成新的白色形状,否则不会除去1-的Δ .这个代码如下.有任何想法吗?

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"];
Run Code Online (Sandbox Code Playgroud)

更新2:我已经解决了其他大多数错误.事实证明,这只是我整个时间都相当愚蠢而且使整个动画过于复杂(更不用说在各处乘以1,什么?).我做了一个我无法解决的bug的gif:

径向控制故障

有任何想法吗?

更新3 :(和关闭).我设法通过调用摆脱了这个bug

[self.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
Run Code Online (Sandbox Code Playgroud)

现在一切正常.感谢您的帮助!

Dun*_*n C 11

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

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