iMa*_*din 9 core-animation objective-c uiview uiviewanimation ios7
我最近发现了一些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) {
}];
}];
}];
}];
Run Code Online (Sandbox Code Playgroud)
这有两个问题:
animateKeyframesWithDuration:delay:options:animations:completion:你应该调用addKeyframeWithRelativeStartTime:relativeDuration:animations:动画块内的方法.如果不调用此方法,则此方法的行为类似于标准UIView动画块.所以我尝试通过正确使用该方法来解决这个问题:
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];
Run Code Online (Sandbox Code Playgroud)
我觉得两个动画应该是相同的,但它们不是.在我的尝试中我做错了什么?
编辑:示例项目(使用Command + T切换模拟器中的慢动画)
Dav*_*ist 17
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
Run Code Online (Sandbox Code Playgroud)
正如你可以看到每个动画有fromValue,但没有toValue或byValue.正如您在文档中看到的那样,这意味着:
fromValue不是nil.插值fromValue和属性的当前显示值.
另一方面,正确地将关键帧添加到动画的第二个版本导致将单个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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它在相同的值之间以相同的时间动画,但在单个关键帧动画中.它也具有相同的总持续时间并使用相同的计时功能.
有一件事我不理解.如果我修改真正的关键帧动画(addAnimation:forKey:在调用super之前重写的内部)以在计时函数数组中显式设置计时函数,那么它们看起来完全相同.也就是说,我在关键帧动画添加到图层之前执行此操作.
CAMediaTimingFunction *function = keyFrame.timingFunction;
keyFrame.timingFunction = nil;
keyFrame.timingFunctions = @[function, function, function, function];
Run Code Online (Sandbox Code Playgroud)
这个技巧非常丑陋,除了纯粹的调试之外你永远不应该使用它!
好吧,我想答案与UIKit在第二种情况下创建的关键帧动画的计时函数数组有关.这几乎是我得到的唯一结论.
也就是说,我不知道这是一个错误还是如何解决它.我只知道你的项目中的代码实际上在Core Animation级别上做了什么.
| 归档时间: |
|
| 查看次数: |
12672 次 |
| 最近记录: |