UIView animateKeyframes 不起作用

Posted

技术标签:

【中文标题】UIView animateKeyframes 不起作用【英文标题】:UIView animateKeyframes not working 【发布时间】:2015-01-27 23:16:29 【问题描述】:

我正在尝试一个关键帧动画,其中视图淡入,然后变换(平移和缩放),然后在延迟后再次变换,然后淡出。我遇到的问题是第二次转换在第一次转换结束后立即开始,而不是尊重延迟值。这似乎只发生在它再次修改变换时,所以我怀疑问题出在尝试在同一个关键帧块中进行两个不同的变换更改,尽管我不明白为什么不允许这样做,因为动画持续时间不重叠。

代码如下:

[UIView animateKeyframesWithDuration:15.0 delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^
        
        [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.1 animations:^
            
            self.imageViewCurrent.alpha = 1.0;
            ];
        [UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.1 animations:^
            
            self.imageViewCurrent.transform = self.imageDataCurrent.transform2;
            ];
        [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.4 animations:^
            
            self.imageViewCurrent.transform = self.imageDataCurrent.transform3;
            ];
        [UIView addKeyframeWithRelativeStartTime:0.9  relativeDuration:0.1 animations:^
            
            self.imageViewCurrent.alpha = 0.0;
            ];
        

这些是正在使用的转换:

开始变换: (a = 5, b = 0, c = 0, d = 5, tx = 950, ty = 850)

变换2: (a = 5, b = 0, c = 0, d = 5, tx = 1250, ty = -1500)

变换3: (a = 2.5, b = 0, c = 0, d = 2.5, tx = -250, ty = 0)

更新 1:

我没有使用自动布局。

更新 2:

我做了更多的测试,并确定确实是两个转换修改导致了问题。如果我用对 alpha 的更改替换其中一个变换修改,则所有动画时间都正常工作。据我所知,这是 UIKit 动画的一个错误。

解决方法:

我发现直接使用核心动画可以避免这个问题。这段代码产生了大致相同的效果,但没有错误:

// Fade in, pause, fade out.
CAKeyframeAnimation *alphaAnim = [CAKeyframeAnimation animationWithKeyPath:@"opacity"];
alphaAnim.keyTimes = @[@(0.0), @(0.1), @(0.9), @(1.0)];
alphaAnim.values = @[@(0.0), @(1.0), @(1.0), @(0.0)];
alphaAnim.duration = 15.0;
[self.imageViewCurrent.layer addAnimation:alphaAnim forKey:@"opacity"];

// Translate, wait on second translation, translate again.
CAKeyframeAnimation *transformAnim = [CAKeyframeAnimation animationWithKeyPath:@"transform"];
transformAnim.keyTimes = @[@(0.3), @(0.4), @(0.5), @(0.8)];
transformAnim.values = @
    [
    [NSValue valueWithCATransform3D:CATransform3DMakeAffineTransform(self.imageDataCurrent.transform1)],
    [NSValue valueWithCATransform3D:CATransform3DMakeAffineTransform(self.imageDataCurrent.transform2)],
    [NSValue valueWithCATransform3D:CATransform3DMakeAffineTransform(self.imageDataCurrent.transform2)],
    [NSValue valueWithCATransform3D:CATransform3DMakeAffineTransform(self.imageDataCurrent.transform3)]
    ];
transformAnim.duration = 15.0;
[self.imageViewCurrent.layer addAnimation:transformAnim forKey:@"transform"];

【问题讨论】:

涉及变换的动画在 ios 8 中的行为确实很奇怪,所以您可能从自己的角度遇到过这种已知的奇怪现象。需要明确一点:您使用的是 Autolayout 吗? 【参考方案1】:

听起来您有一个时间轴,其中包含动画运行和“休息”的周期。我建议您将其余部分作为带有空动画块的关键帧输入。

类似这样的:

[UIView animateKeyframesWithDuration:15.0 delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeLinear animations:^
  

    [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.1 animations:^
    
      self.imageViewCurrent.alpha = 1.0;
    ];

    [UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.1 animations:^
    
      self.imageViewCurrent.transform = self.imageDataCurrent.transform2;
    ];

    //Create an empty keyframe
    [UIView addKeyframeWithRelativeStartTime:0.2 relativeDuration:0.3 animations:^
    
    ];

    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.4 animations:^
    
      self.imageViewCurrent.transform = self.imageDataCurrent.transform3;
    ];

    [UIView addKeyframeWithRelativeStartTime:0.9  relativeDuration:0.1 animations:^
    
      self.imageViewCurrent.alpha = 0.0;
    ];
  

【讨论】:

不幸的是,这对我不起作用,第二个变换动画仍然在第一个变换动画结束后立即开始。

以上是关于UIView animateKeyframes 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

UIView.animateKeyframes 跳转到下一个动画的开始而不是平滑过渡

UIView.animateKeyframes 中的第二个关键帧没有被调用

如何消除 animateKeyframes 动画开始和结束的延迟 - Swift UIKit

如何根据后者的进度为已经运行的动画添加动画?

UIView 类别 - 自定义方法不返回 UIView

当我将 UIView 动画放在不同类的 containerView 中时,为啥我的 UIView 动画不起作用?