2016-12-25 46 views
0

我正在尝试创建绘制的无限跟踪路径,并且它的背面消失。但是,我使代码在单次迭代后消失。实际上,图层在路径消失动画完成之前消失。它看起来像是在绘图动画完成时消失。CAShapeLayer的CABasicAnimation在它完成之前消失,并且不会无限地继续

此外,一旦它消失,在再次开始之前,它再次不会再出现几秒(可能无论多长时间,动画需要重复)。

两个问题:

  1. 为什么层消失的消失动画完成之前?

  2. 如何让动画连续播放而不消失?

预先感谢您!这里是我的代码:

CGRect boundingFrame = CGRectMake(CGRectGetMidX(self.bounds) - 48.0, CGRectGetMidY(self.bounds) - 48.0, 96.0, 96.0); 

_pathPoints = @[ 
       [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(boundingFrame), CGRectGetMinY(boundingFrame) + squareSideWidth/2.0)], 
       [NSValue valueWithCGPoint:CGPointMake(CGRectGetMinX(boundingFrame) + squareSideWidth/2.0, CGRectGetMidY(boundingFrame))], 
       [NSValue valueWithCGPoint:CGPointMake(CGRectGetMidX(boundingFrame), CGRectGetMaxY(boundingFrame) - squareSideWidth/2.0)], 
       [NSValue valueWithCGPoint:CGPointMake(CGRectGetMaxX(boundingFrame) - squareSideWidth/2.0, CGRectGetMidY(boundingFrame))] 
       ]; 

CAShapeLayer *line = [CAShapeLayer layer]; 
line.path = pathForPoints(_pathPoints).CGPath; 
line.lineCap = kCALineCapRound; 
line.strokeColor = color.CGColor; 
line.fillColor = [UIColor clearColor].CGColor; 
line.strokeEnd = 0.0; 
[self.layer addSublayer:line]; 

NSMutableArray<CABasicAnimation *> *animations = [NSMutableArray new]; 
for (int i = 0; i < [_pathPoints count]; i++) { 
    CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
    drawAnimation.beginTime = index; 
    drawAnimation.duration = 1.0; 
    drawAnimation.fromValue = @(strokeEndForIndex(points, index - 1)); 
    drawAnimation.toValue = @(strokeEndForIndex(points, index)); 
    drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    drawAnimation.additive = YES; 
    drawAnimation.removedOnCompletion = NO; 

    CABasicAnimation *eraseAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; 
    eraseAnimation.beginTime = index + 0.75; 
    eraseAnimation.duration = 1.0; 
    eraseAnimation.fromValue = @(strokeEndForIndex(points, index - 1)); 
    eraseAnimation.toValue = @(strokeEndForIndex(points, index)); 
    eraseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    eraseAnimation.additive = YES; 
    eraseAnimation.removedOnCompletion = NO; 

    CAAnimationGroup *group = [CAAnimationGroup animation]; 
    group.animations = @[drawAnimation, eraseAnimation]; 
    group.duration = 2.0 * [animations count]; 
    group.repeatCount = INFINITY; 
    group.removedOnCompletion = NO; 
    [line addAnimation:group forKey:@"line"]; 
} 

助手功能,以供参考:

static CGFloat lengthOfPathWithPoints(NSArray<NSValue *> *points) 
{ 
    CGFloat totalDist = 0; 
    for (int i = 0; i < [points count]; i++) { 
     CGFloat xDist = [points[i % [points count]] CGPointValue].x - [points[(i + 1) % [points count]] CGPointValue].x; 
     CGFloat yDist = [points[i % [points count]] CGPointValue].y - [points[(i + 1) % [points count]] CGPointValue].y; 
     totalDist += sqrt(pow(xDist, 2) + pow(yDist, 2)); 
    } 
    return totalDist; 
} 

static CGFloat strokeEndForIndex(NSArray<NSValue *> *points, int index) 
{ 
    // If it's the last index, just return 1 early 
    if (index == [points count] - 1) { 
     return 1.0; 
    } 
    // In the case where index = -1 (as it does for the initial erase animation fromValue), just return 0 
    if (index < 0) { 
     return 0.0; 
    } 

    CGFloat totalDist = 0; 
    for (int i = 0; i < index + 1; i++) { 
     CGFloat xDist = [points[i % [points count]] CGPointValue].x - [points[(i + 1) % [points count]] CGPointValue].x; 
     CGFloat yDist = [points[i % [points count]] CGPointValue].y - [points[(i + 1) % [points count]] CGPointValue].y; 
     totalDist += sqrt(pow(xDist, 2) + pow(yDist, 2)); 
    } 

    return totalDist/lengthOfPathWithPoints(points); 
} 

static UIBezierPath *pathForPoints(NSArray<NSValue *> *points) 
{ 
    UIBezierPath *path = [UIBezierPath new]; 
    [path moveToPoint:[[points firstObject] CGPointValue]]; 
    for (int i = 0; i < [points count]; i++) { 
     [path addLineToPoint:[points[(i + 1) % 4] CGPointValue]]; 
    } 
    return path; 
} 

回答

0

提高飞行时间的属性值,改变你的repeatCount =浮动(Int.max)到这样的事情。

+0

谢谢!给了这一枪,没有任何运气。 – Mason

相关问题