微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

objective-c – UIView animateKeyframesWithDuration vs标准动画块动画不同

我最近发现一些UIView动画代码,并注意到它没有使用animateKeyframesWithDuration:delay:options:animations:completion:方法正确,并且一直在尝试修复它,但由于某些原因,动画是不一样的.

这是我发现的代码

view.transform = CGAffineTransformMakeTranslation(300,0);

[UIView animateKeyframesWithDuration:duration/4 delay:delay options:0 animations:^{
    // End
    view.transform = CGAffineTransformMakeTranslation(-10,0);
} completion:^(BOOL finished) {
    [UIView animateKeyframesWithDuration:duration/4 delay:0 options:0 animations:^{
        // End
        view.transform = CGAffineTransformMakeTranslation(5,0);
    } completion:^(BOOL finished) {
        [UIView animateKeyframesWithDuration:duration/4 delay:0 options:0 animations:^{
            // End
            view.transform = CGAffineTransformMakeTranslation(-2,0);
        } completion:^(BOOL finished) {
            [UIView animateKeyframesWithDuration:duration/4 delay:0 options:0 animations:^{
                // End
                view.transform = CGAffineTransformMakeTranslation(0,0);
            } completion:^(BOOL finished) {
            }];
        }];
    }];
}];

这有两个问题:

>应该真正使用关键帧动画,而不是在完成块中嵌套动画.
>当使用animateKeyframesWithDuration:delay:options:animations:completion:你应该调用addKeyframeWithRelativeStartTime:relativeDuration:动画块中的动画:方法.如果你不调用这个方法,那么这个方法的行为就像一个标准的UIView动画块.

See Apple’s documentation regarding this method here.

所以我试图通过正确的方法解决这个问题:

view.transform = CGAffineTransformMakeTranslation(300,0);
double frameDuration = 1.0/4.0; // 4 = number of keyframes

[UIView animateKeyframesWithDuration:duration delay:delay options:0 animations:^{
    [UIView addKeyframeWithRelativeStartTime:0*frameDuration relativeDuration:frameDuration animations:^{
        view.transform = CGAffineTransformMakeTranslation(-10,0);
    }];
    [UIView addKeyframeWithRelativeStartTime:1*frameDuration relativeDuration:frameDuration animations:^{
        view.transform = CGAffineTransformMakeTranslation(5,0);
    }];
    [UIView addKeyframeWithRelativeStartTime:2*frameDuration relativeDuration:frameDuration animations:^{
        view.transform = CGAffineTransformMakeTranslation(-2,0);
    }];
    [UIView addKeyframeWithRelativeStartTime:3*frameDuration relativeDuration:frameDuration animations:^{
        view.transform = CGAffineTransformMakeTranslation(0,0);
    }];
} completion:nil];

我觉得这两个动画都应该是一样的,但是不是这样.我的尝试做错了什么?

编辑:Example project(使用命令T来切换模拟器中的慢速动画)

解决方法

tl; dr:他们可能看起来不同,因为他们做不同的事情,并导致不同的动画被添加到两个视图.不幸的是,我真的不知道如何解决它.

第一版后面发生了什么

正如您已经说过的第一个版本不正确使用API​​.它不使用addKeyframeWithRelativeStartTime添加关键帧:relativeDuration:animations:而是直接在动画块内更改属性.然后,它将在完成块中创建一个新的“关键帧动画”(您将很快看到为什么我使用吓唬报价).

在幕后,这并不会导致CAKeyframeAnimations(虽然我不认为你应该依赖于这个事实).这是我在四个动画对象中添加到项目中的view1后面层中的一些记录. (我被骗了一点,只记录了.m41部分的变换(对应于x的翻译)).

BASIC
keyPath: transform
duration: 0.125
from: 300.0
model value: -10.0
timing: easeInEaSEOut

BASIC
keyPath: transform
duration: 0.125
from: -10.0
model value: 5.0
timing: easeInEaSEOut

BASIC
keyPath: transform
duration: 0.125
from: 5.0
model value: -2.0
timing: easeInEaSEOut

BASIC
keyPath: transform
duration: 0.125
from: -2.0
model value: 0.0
timing: easeInEaSEOut

你可以看到每个动画都有一个fromValue,但是没有tovalue或者byValue.您可以在文档中阅读,这意味着:

fromValue is non-nil. Interpolates between fromValue and the current presentation value of the property.

第二版后面发生了什么

另一方面,向动画正确添加关键帧的第二个版本会导致将此单个CAKeyframeAnimation添加到view2后面的层中. (我仍然只记录.m41部分的变换)

KEYFRAME 
keyPath: transform
duration: 0.500
values: (
    300,-10,5,-2,0
)
keyTimes: (
    0.0,0.25,0.5,0.75,1.0
)
timing: easeInEaSEOut
timings: (nil)
calculationMode: linear

正如你可以看到,它在相同的值之间在相同的时间,但在一个关键帧动画动画.它也具有相同的总持续时间并使用相同的定时功能.

有一件事我不明白.如果我修改真正的关键帧动画(在我重写的addAnimation内部:forKey:在调用super之前)显式地设置定时功能阵列中的定时功能,那么它们看起来完全相同.也就是说,我在关键帧动画添加到图层之前做到这一点.

camediatimingFunction *function = keyFrame.timingFunction;
keyFrame.timingFunction = nil;
keyFrame.timingFunctions = @[function,function,function];

这个伎俩是非常丑陋的,你绝对不应该使用它,除了纯粹的调试之外的事情!

那为什么他们看起来不一样?

那么,我想这个答案与UIKit在第二种情况下创建的关键帧动画的时序函数数组有关.这几乎是我得到的唯一结论.

也就是说,我不知道这是一个bug还是修复它.我只是知道您的项目中的代码实际上在核心动画级别.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐