ios - 使用 [UIView animateKeyframesWithDuration] 为 UIView 设置动画的奇怪行为

标签 ios objective-c animation core-animation

我正在尝试创建一种效果,其中三个箭头交替地从可见变为不可见。

我做了一个简单的算法,其中每个箭头都从不同的 alpha 值开始(如果有 3 个箭头,第一个将从 alpha=1 开始,第二个从 alpha=0.6667 开始,第三个从 alpha=0.3337 开始).然后我开始一个关键帧动画:

  • 将箭头的不透明度从当前的 alpha 更改为 0(计算持续时间)
  • 立即将箭头不透明度设置为 1
  • 将箭头不透明度从 1 更改为第一个值集

然而,由于某些原因似乎跳过了某些步骤。

一个简单的例子:

[UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear | UIViewKeyframeAnimationOptionRepeat animations:^{

    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0 animations:^{
        _animatedView.alpha = 0.5;
    }];

    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0.5 animations:^{
        _animatedView.alpha = 0;
    }];

    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0 animations:^{
        _animatedView.alpha = 1;
    }];

    [UIView addKeyframeWithRelativeStartTime:0.5 relativeDuration:0.5 animations:^{
        _animatedView.alpha = 0.5;
    }];

} completion:nil];

在那种情况下,它应该立即变为 0.5,1 秒内从 0.5 变为 0,立即变​​为 1,1 秒内从 1 变为 0.5。因此,它应该做一个无缝过渡,看起来像 View 出现和消失,但看起来动画在 alpha=0.5 上停留了一段时间。

理论上和使用这个关键帧动画效果应该是一样的:

[UIView animateKeyframesWithDuration:2 delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear | UIViewKeyframeAnimationOptionRepeat animations:^{
    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0 animations:^{
        _animatedView.alpha = 1;
    }];
    [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:1 animations:^{
        _animatedView.alpha = 0;
    }];
} completion:nil];

最佳答案

如果您想以相同的方式为 N 个 View 设置动画:

CGFloat count = [self.animatedViews count];
CGFloat period = 1.0f / count;

__weak NSArray *weakViews = self.animatedViews;

[UIView animateKeyframesWithDuration:2.0f delay:0 options:UIViewKeyframeAnimationOptionCalculationModeLinear | UIViewKeyframeAnimationOptionRepeat animations:^{

    for (NSUInteger index = 0; index < count; ++index) {
        UIView *animatedView = weakViews[index];

        CGFloat startDelay = period * index;

        [UIView addKeyframeWithRelativeStartTime:0 relativeDuration:0 animations:^{
            animatedView.alpha = startDelay;
        }];

        [UIView addKeyframeWithRelativeStartTime:0.0f relativeDuration:startDelay animations:^{
            animatedView.alpha = 0.0f;
        }];

        [UIView addKeyframeWithRelativeStartTime:startDelay relativeDuration:0.0f animations:^{
            animatedView.alpha = 1.0f;
        }];

        [UIView addKeyframeWithRelativeStartTime:startDelay relativeDuration:(1.0f - startDelay) animations:^{
            animatedView.alpha = startDelay;
        }];
    }
} completion:nil];

关于ios - 使用 [UIView animateKeyframesWithDuration] 为 UIView 设置动画的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25552811/

相关文章:

ios - Xcode 不按照目标依赖项中指定的顺序运行测试目标

ios - 如何在单例方法中实现 AVAudioPlayer?

objective-c - 将非拥有的窗口设置为始终在顶部 - 就像应用程序 "Afloat"

jquery - IE8 中的 setTimeout 与 jquery jstween 动画循环

iphone - 获取TMXTiledMap的tileet文件名

ios - 未调用自定义委托(delegate)方法

ios - 从子上下文分配对象时非法尝试建立关系

ios - 在 iOS 中使用 AVFoundation Framework 来自相机的视频帧?

javascript - 每个卷轴都会带您到一个新的 div 以启用动画

javascript - javascript 中的平滑滚动?