gpt4 book ai didi

objective-c - UIView animateKeyframesWithDuration 与标准动画 block 动画不同

转载 作者:太空狗 更新时间:2023-10-30 03:28:11 26 4
gpt4 key购买 nike

我最近发现了一些 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) {
}];
}];
}];
}];

这有两个问题:

  1. 真正应该使用关键帧动画而不是在完成 block 中嵌套动画。
  2. 使用 animateKeyframesWithDuration:delay:options:animations:completion: 时,您应该在动画 block 中调用 addKeyframeWithRelativeStartTime:relativeDuration:animations: 方法。如果您不调用此方法,则此方法的行为类似于标准的 UIView 动画 block 。

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 (使用 Command + T 在模拟器中切换慢速动画)

最佳答案

tl;dr:它们看起来不同可能是因为它们执行不同的操作并导致向两个 View 添加不同的动画。不幸的是,我真的不知道如何修复它。

第一个版本背后发生了什么

正如您所说,第一个版本没有正确使用 API。它不使用 addKeyframeWithRelativeStartTime:relativeDuration:animations: 添加关键帧,而是直接在动画 block 内更改属性。然后它在完成 block 中创建一个新的“关键帧动画”(您很快就会明白为什么我在那里使用恐吓引号)。

在幕后,这实际上不会产生 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

如您所见,它在相同时间的相同值之间进行动画处理,但在单个关键帧动画中。它还具有相同的总持续时间并使用相同的计时功能。

有一件事我不明白。如果我修改真正的关键帧动画(在调用 super 之前在我重写的 addAnimation:forKey: 内部)以明确设置计时函数数组中的计时函数,那么它们看起来确实完全一样。也就是说,我在将关键帧动画添加到图层之前对它执行此操作。

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

这个技巧非常丑陋,除了纯粹的调试之外,你不应该将它用于其他事情!


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

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

就是说,我不知道这是否是错误或如何修复它。我只知道您项目中的代码在核心动画级别上实际做了什么。

关于objective-c - UIView animateKeyframesWithDuration 与标准动画 block 动画不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22342802/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com