2016-06-28 13 views
3

Я пытаюсь применить анимацию вращения по количеству градусов до UIImageView и сохранить преобразование вращения в блоке завершения.CABasicAnimation мерцание при применении завершения

Проблема, с которой я столкнулась, заключается в том, что при выполнении блока завершения происходит видимое мерцание, генерируемое путем перехода от конечного состояния анимации к блоку завершения.

Вот код, который я в настоящее время с помощью:

if (futureAngle == currentAngle) { 
    return; 
} 

float rotationAngle; 
if (futureAngle < currentAngle) { 
    rotationAngle = futureAngle - currentAngle; 
}else{ 
    rotationAngle = futureAngle - currentAngle; 
} 

float animationDuration = fabs(rotationAngle)/100; 
rotationAngle = GLKMathDegreesToRadians(rotationAngle); 

[CATransaction begin]; 
CABasicAnimation *rotationAnimation; 
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
rotationAnimation.byValue = [NSNumber numberWithFloat:rotationAngle]; 
rotationAnimation.duration = animationDuration; 
rotationAnimation.removedOnCompletion = YES; 

[CATransaction setCompletionBlock:^{ 
    view.transform = CGAffineTransformRotate(view.transform, rotationAngle); 
}]; 

[view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
[CATransaction commit]; 
+0

Когда вы говорите, мерцать, я полагаю, вы имеете в виду, что в конце анимации, что это мгновенно возвращается в исходное состояние, прежде чем вернуться в конечное состояние? Это можно решить либо путем (a) установки окончательного 'view.transform'_before_, который вы запускаете анимацию (и вам больше не нужен' completeBlock'); или (b), установив «fillMode» анимации в 'kCAFillModeForwards' и установите' removedOnCompletion' в 'false'. – Rob

+0

См. Http://oleb.net/blog/2012/11/prevent-caanimation-snap-back/ или http://stackoverflow.com/a/31010421/1271826 или http://stackoverflow.com/a/7690841/1271826 – Rob

+0

@Rob вы можете привести пример предложения относительно блока завершения? Я попробовал fillMode для kCAFillModeForwards и установил removeOnCompletion в false до создания сообщения, и они не сработали для меня. –

ответ

6

Когда вы говорите, мерцать, я полагаю, вы имеете в виду, что в конце анимации, что она мгновенно возвращается в исходное состояние, прежде чем вернуться обратно конечное состояние? Это можно решить либо

  • установка окончательного view.transform перед началом анимации (и вам больше не требуется завершение);
  • , установив fillMode анимации на kCAFillModeForwards и установите removedOnCompletion на false.

Лично я считаю, что установка анимированного свойства до значения назначения перед началом анимации - это самый простой способ сделать это.

Таким образом:

- (void)rotate:(UIView *)view by:(CGFloat)delta { 
    float animationDuration = 2.0; 
    CGFloat currentAngle = self.angle;             // retrieve saved angle 
    CGFloat nextAngle = self.angle + delta;            // increment it 
    self.angle = nextAngle;                // save new value 

    view.transform = CGAffineTransformMakeRotation(nextAngle);       // set property to destination rotation 

    CABasicAnimation *rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; // now rotate 
    rotationAnimation.fromValue = @(currentAngle); 
    rotationAnimation.toValue = @(nextAngle); 
    rotationAnimation.duration = animationDuration; 
    rotationAnimation.removedOnCompletion = YES; 
    [view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 

Или, я думаю, что еще проще, просто настроить transform:

- (void)rotate:(UIView *)view by:(CGFloat)delta { 
    float animationDuration = 2.0; 
    CGAffineTransform transform = view.transform;           // retrieve current transform 
    CGAffineTransform nextTransform = CGAffineTransformRotate(transform, delta);   // increment it 

    view.transform = nextTransform;              // set property to destination rotation 

    CABasicAnimation *rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];    // now rotate 
    rotationAnimation.fromValue = [NSValue valueWithCGAffineTransform:transform]; 
    rotationAnimation.toValue = [NSValue valueWithCGAffineTransform:nextTransform]; 
    rotationAnimation.duration = animationDuration; 
    rotationAnimation.removedOnCompletion = YES; 
    [view.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 
+0

Увлекательный, казалось бы, что * если вы пытаетесь сделать UIView.animate в одно и то же время * (скажем, просто перемещая ограничение), «метод fillMode» кажется ответом ........ , – Fattie