2016-12-25 3 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

은 기간 속성 값을 증가시키고이 같은에 반복 횟수 = 플로트 (Int.max)을 변경합니다.

+0

고마워요! 이걸 쐈어. 운이 없었어. – Mason

관련 문제