Ios CAShapeLayer动画没有';不要停留在屏幕上,而是消失

Ios CAShapeLayer动画没有';不要停留在屏幕上,而是消失,ios,objective-c,cashapelayer,catransaction,Ios,Objective C,Cashapelayer,Catransaction,我试图画一个动画圆圈,但每个部分都需要另一种颜色。现在一切都正常了,除了在我再次调用该方法之前刚刚绘制的片段消失了,所以只有最后一部分保留了下来。我不希望这样,我希望在4次之后,用不同的颜色笔划画出一个完整的圆 我怎样才能修复它,使它不会消失 这是我的初始代码: - (void)_initCircle { _circle = [CAShapeLayer layer]; _radius = 100; // Make a circular shape _circle

我试图画一个动画圆圈,但每个部分都需要另一种颜色。现在一切都正常了,除了在我再次调用该方法之前刚刚绘制的片段消失了,所以只有最后一部分保留了下来。我不希望这样,我希望在4次之后,用不同的颜色笔划画出一个完整的圆

我怎样才能修复它,使它不会消失

这是我的初始代码:

- (void)_initCircle {
    _circle = [CAShapeLayer layer];
    _radius = 100;

    // Make a circular shape
    _circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * _radius, 2.0 * _radius) cornerRadius:_radius].CGPath;

    // Center the shape in self.view
    _circle.position = CGPointMake(CGRectGetMidX(self.view.frame) - _radius,
                                   CGRectGetMidY(self.view.frame) - _radius);

    _circle.fillColor = [UIColor clearColor].CGColor;
    _circle.lineWidth = 5;

    // Add to parent layer
    [self.view.layer addSublayer:_circle];
}
这是我的画:

- (void)_drawStrokeOnCircleFrom:(float)start to:(float)end withColor:(UIColor *)color {
    // Configure the apperence of the circle
    _circle.strokeColor = color.CGColor;
    _circle.strokeStart = start;
    _circle.strokeEnd = end;

       [CATransaction begin];

    // Configure animation
    CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    drawAnimation.duration            = 2.0; // "animate over 10 seconds or so.."
    drawAnimation.repeatCount         = 1.0;  // Animate only once..

    // Animate from no part of the stroke being drawn to the entire stroke being drawn
    drawAnimation.fromValue = [NSNumber numberWithFloat:start];
    drawAnimation.toValue   = [NSNumber numberWithFloat:end];

    // Experiment with timing to get the appearence to look the way you want
    drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];

    [CATransaction setCompletionBlock:^{
        NSLog(@"Complete animation");
        _index++;
        if(_index < _votes.count){
        _startStroke = _endStroke;
        _endStroke += [_votes[_index] floatValue] / _totalListens;
        [self _drawStrokeOnCircleFrom:_startStroke to:_endStroke withColor:_colors[_index]];
        }

    }];

    // Add the animation to the circle
    [_circle addAnimation:drawAnimation forKey:@"drawCircleAnimation"];

       [CATransaction commit];
}
-(void)\u drawStrokeOnCircleFrom:(float)开始到:(float)结束于color:(UIColor*)color{
//配置圆的外观
_circle.strokeColor=color.CGColor;
_circle.strokeStart=开始;
_circle.strokeEnd=结束;
[交易开始];
//配置动画
CABasicAnimation*drawAnimation=[CABasicAnimation animationWithKeyPath:@“strokeEnd”];
drawAnimation.duration=2.0;/“动画制作时间超过10秒左右…”
drawAnimation.repeatCount=1.0;//仅设置一次动画。。
//从正在绘制的笔划的任何部分到正在绘制的整个笔划设置动画
drawAnimation.fromValue=[NSNumber numberWithFloat:start];
drawAnimation.toValue=[NSNumber numberWithFloat:end];
//尝试计时,让外观看起来像你想要的样子
drawAnimation.timingFunction=[CamediaTimingFunctionWithName:KCAMediaTimingFunctionAsein];
[CATTransaction setCompletionBlock:^{
NSLog(“完整动画”);
_索引++;
如果(指数<票数){
_开始行程=_结束行程;
_endStroke+=[\u投票[\u指数]浮动值]/\u总计;
[self _DrawStrokeonCirclefom:_StartStroketo:_EndStrokeWith Color:_colors[_index]];
}
}];
//将动画添加到圆中
[_circleaddanimation:drawAnimation forKey:@“drawCircleAnimation”];
[CATransaction-commit];
}

尝试在您的CABasicAnimation上设置这些值:

drawAnimation.removedOnCompletion = NO;
drawAnimation.fillMode = kCAFillModeForwards;

我用这样的附加层解决了这个问题:

- (void)_drawStrokeOnCircle {

    [self _initCircle];

    [CATransaction begin];

    for (NSUInteger i = 0; i < 4; i++)
    {
        CAShapeLayer* strokePart = [[CAShapeLayer alloc] init];
        strokePart.fillColor = [[UIColor clearColor] CGColor];
        strokePart.frame = _circle.bounds;
        strokePart.path = _circle.path;
        strokePart.lineCap = _circle.lineCap;
        strokePart.lineWidth = _circle.lineWidth;


        // Configure the apperence of the circle
        strokePart.strokeColor = ((UIColor *)_colors[i]).CGColor;
        strokePart.strokeStart = [_segmentsStart[i] floatValue];
        strokePart.strokeEnd = [_segmentsEnd[i] floatValue];

        [_circle addSublayer: strokePart];

        // Configure animation
        CAKeyframeAnimation* drawAnimation = [CAKeyframeAnimation animationWithKeyPath: @"strokeEnd"];
        drawAnimation.duration            = 4.0;

        // Animate from no part of the stroke being drawn to the entire stroke being drawn
        NSArray* times = @[ @(0.0),
                            @(strokePart.strokeStart),
                            @(strokePart.strokeEnd),
                            @(1.0) ];
        NSArray* values = @[ @(strokePart.strokeStart),
                             @(strokePart.strokeStart),
                             @(strokePart.strokeEnd),
                             @(strokePart.strokeEnd) ];

        drawAnimation.keyTimes = times;
        drawAnimation.values = values;
        drawAnimation.removedOnCompletion = NO;
        drawAnimation.fillMode = kCAFillModeForwards;

        // Experiment with timing to get the appearence to look the way you want
        drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];


        [strokePart addAnimation: drawAnimation forKey: @"drawCircleAnimation"];
    }
    [CATransaction commit];
}

- (void)_initCircle {
    [_circle removeFromSuperlayer];
    _circle = [CAShapeLayer layer];
    _radius = 100;

    // Make a circular shape
    _circle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * _radius, 2.0 * _radius) cornerRadius:_radius].CGPath;

    // Center the shape in self.view
    _circle.position = CGPointMake(CGRectGetMidX(self.view.frame) - _radius,
                                   CGRectGetMidY(self.view.frame) - _radius);

    _circle.fillColor = [UIColor clearColor].CGColor;
    _circle.lineWidth = 5;

    // Add to parent layer
    [self.view.layer addSublayer:_circle];
}
-(无效)\u drawStrokeOnCircle{
[self_initCircle];
[交易开始];
对于(整数i=0;i<4;i++)
{
CAShapeLayer*strokePart=[[CAShapeLayer alloc]init];
strokePart.fillColor=[[UIColor clearColor]CGColor];
strokePart.frame=\u circle.bounds;
strokePart.path=_circle.path;
strokePart.lineCap=_circle.lineCap;
strokePart.lineWidth=_circle.lineWidth;
//配置圆的外观
strokePart.strokeColor=((UIColor*)_colors[i]).CGColor;
strokePart.strokeStart=[[u段开始[i]浮点值];
strokePart.strokeEnd=[[u段发送[i]浮点值];
[_circleaddsublayer:strokePart];
//配置动画
CAKeyframeAnimation*drawAnimation=[CAKeyframeAnimation animationWithKeyPath:@“strokeEnd”];
drawAnimation.duration=4.0;
//从正在绘制的笔划的任何部分到正在绘制的整个笔划设置动画
NSArray*时间=@[@(0.0),
@(strokePart.strokeStart),
@(strokePart.strokeEnd),
@(1.0) ];
NSArray*值=@[@(strokePart.strokeStart),
@(strokePart.strokeStart),
@(strokePart.strokeEnd),
@(strokePart.strokeEnd)];
drawAnimation.keyTimes=次;
drawAnimation.values=值;
drawAnimation.removedOnCompletion=否;
drawAnimation.fillMode=kCAFillModeForwards;
//尝试计时,让外观看起来像你想要的样子
drawAnimation.timingFunction=[CamediaTimingFunctionWithName:KCAMediaTimingFunctionAsein];
[strokePart addAnimation:drawAnimation-forKey:@“drawCircleAnimation”];
}
[CATransaction-commit];
}
-(无效){
[_从超级层移除圆圈];
_圆圈=[CAShapeLayer layer];
_半径=100;
//做成圆形
_circle.path=[UIBezierPath bezierPathWithRoundedRect:CGRectMake(0,0,2.0*\u半径,2.0*\u半径)cornerRadius:\u半径].CGPath;
//在self.view中将形状居中
_circle.position=CGPointMake(CGRectGetMidX(self.view.frame)——\u半径,
CGRectGetMidY(self.view.frame)——\u半径);
_circle.fillColor=[UIColor clearColor].CGColor;
_圆形。线宽=5;
//添加到父层
[self.view.layer addSublayer:_circle];
}
使用“KCAFILLMODEATH”对我有效,这两个语句都是必需的:

//to keep it after finished
animation.removedOnCompletion = false;
animation.fillMode = kCAFillModeBoth;

SWIFT 4,代码11:

let strokeIt = CABasicAnimation(keyPath: "strokeEnd")
let timeLeftShapeLayer = CAShapeLayer()
在您的
视图中加载

  override func viewDidLoad() {
    super.viewDidLoad()
    drawTimeLeftShape()
    strokeIt.fillMode = CAMediaTimingFillMode.forwards
    strokeIt.isRemovedOnCompletion = false
    strokeIt.fromValue = 0
    strokeIt.toValue = 1
    strokeIt.duration = 2
    timeLeftShapeLayer.add(strokeIt, forKey: nil)
  }
并通过
UIBezierPath
create函数绘制圆:

func drawTimeLeftShape() {
        timeLeftShapeLayer.path = UIBezierPath(
            arcCenter: CGPoint(x: myView.frame.midX , y: myView.frame.midY),
            radius: myView.frame.width / 2,
            startAngle: -90.degreesToRadians,
            endAngle: 270.degreesToRadians,
            clockwise: true
        ).cgPath
        timeLeftShapeLayer.strokeColor = UIColor.red.cgColor
        timeLeftShapeLayer.fillColor = UIColor.clear.cgColor
        timeLeftShapeLayer.lineWidth = 1
        timeLeftShapeLayer.strokeEnd = 0.0
        view.layer.addSublayer(timeLeftShapeLayer)
    }

对不起,我把你的问题搞错了。这两行代码在动画完成后保持持久性,这是您需要的。但如果我没弄错的话,你还想画一幅多色的画?然后你需要有多个图层,每个图层都有一个不同颜色的笔划段。我需要更多的层次。我已经发布了我的解决方案:)谢谢你的帮助,顺便说一句。添加了fillmode,removedOnCompletion不再需要了。