Ios 设置循环路径的动画

Ios 设置循环路径的动画,ios,objective-c,core-animation,uibezierpath,cadisplaylink,Ios,Objective C,Core Animation,Uibezierpath,Cadisplaylink,我有一个项目,我正在根据设定的进度为UIBezierPath制作动画。BezierPath呈圆形,位于UIView中,动画现在使用CADisplayLink在drawRect中完成。简单地说,根据设置的进度x路径应该径向延伸(如果x比以前大)或收缩(如果x比以前小) 这是自上次更新以来x收缩的情况。我遇到的问题实际上有几个: 形状总是在45º开始绘制(除非我旋转视图)。我没有找到任何方法来改变这一点,将startAngle设置为-45º实际上没有什么区别,因为它总是“砰砰”地跳到45º。我能做些

我有一个项目,我正在根据设定的进度为UIBezierPath制作动画。BezierPath呈圆形,位于UIView中,动画现在使用CADisplayLink在drawRect中完成。简单地说,根据设置的进度
x
路径应该径向延伸(如果
x
比以前大)或收缩(如果
x
比以前小)

这是自上次更新以来
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:我已经解决了大多数其他bug。结果是我一直都很傻,把整个动画复杂化了(更不用说到处乘以1了,什么?)。我制作了一个无法解决的错误的gif:

    有什么想法吗

    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"];
    
    更新3:(和结束)。我打电话设法摆脱了这个错误

    [self.layer.sublayers makeObjectsPerformSelector:@selector(removeFromSuperlayer)];
    

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

    使用CAShapeLayer更容易、更干净。原因是CAShapeLayer包含属性strokeStart和strokeEnd。这些值的范围从0(路径的起点)到1(路径的终点),并且可以设置动画


    通过更改这些属性,您可以轻松绘制圆的任何圆弧(或任意路径的任何部分)。这些属性是可设置动画的,因此您可以创建不断增长/收缩的饼图切片或环形部分的动画。与在drawRect中实现代码相比,它更简单、更高效。

    您是否希望执行类似的操作?我已经迁移到使用CAShapeLayer+Cabasicanization,因为似乎有更合理的选择,部分原因是能够使用Duncan推荐的属性。在Swift中寻找一个好的解决方案。这实际上简化了很多事情,我将代码迁移到使用基于CAShapeLayer和Cabasicanization的解决方案,因此非常感谢!然而,现在我经历了一个不同的怪事…那是什么怪事?