应用完成时,CABasicAnimation会闪烁

Lau*_*fan 5 objective-c cabasicanimation ios catransaction

我试图将旋转动画按度数应用于a UIImageView并在完成块中保持旋转变换.

我面临的问题是,当执行完成块时,通过从动画的结束状态传递到完成块产生可见的闪烁.

这是我目前使用的代码:

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];
Run Code Online (Sandbox Code Playgroud)

Rob*_*Rob 13

当你说闪烁时,我认为你的意思是在动画结束时,它会在返回到最终状态之前暂时返回到初始状态?这可以通过以下方式解决

  • view.transform在开始动画之前设置最终(并且您不再需要completionBlock);
  • 通过将动画设置fillModekCAFillModeForwards并设置removedOnCompletionfalse.

就个人而言,我认为在开始动画之前将动画属性设置为其目标值是最简单的方法.

从而:

- (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"];
}
Run Code Online (Sandbox Code Playgroud)

或者,我认为更简单,只需调整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"];
}
Run Code Online (Sandbox Code Playgroud)


Fon*_*nix 6

即使使用罗布的建议答案,我也看到闪烁,但事实证明这似乎只是一个模拟器错误。在真实设备上,我看不到闪烁,如果您只在模拟器上进行测试,请尝试在真实设备上,除非您想像我一样浪费生命的时间。