我想让我的CALayer动画显示一段时间,然后淡出,这是我的代码
[_msgLayer removeAllAnimations];
[UIView animateWithDuration:10 delay:0 options:0 animations:^ {
_msgLayer.hidden = false;
NSLog(@"showing");
} completion:^(BOOL finished) {
NSLog(@"showing done, finished=%d", finished);
[UIView animateWithDuration:10 delay:40 options:0 animations:^ {
_msgLayer.hidden = true;
} completion:^(BOOL hideFinished) {
NSLog(@"hiding done, finished=%d", hideFinished);
}];
}];
然而,动画根本没有像我预期的那样工作,一切都几乎立即完成
2014-10-26 10:11:28.249 Foobar[91761:6827358] showing
2014-10-26 10:11:28.254 Foobar[91761:6827358] showing done, finished=1
2014-10-26 10:11:28.255 Foobar[91761:6827358] hiding done, finished=1
我看到一些类似的问题,有些人说hidden
不可动画,但文档说它可以动画。我也尝试opacity
,然后同样的结果,动画仍然立即完成。这是为什么?我该如何解决?
_msgLayer
是我自己的类继承CALayer,它有自己的绘图方法。这个动画是从网络事件调用的,就像服务器向iPhone发送消息一样,然后我在屏幕上显示消息。
答案 0 :(得分:6)
问题在于UIView动画用于动画视图。
使用UIView动画时发生的事情的高概述是块被执行,这会更改视图的属性,而视图的属性又会更改背景层(或直接更改图层属性)。当(支持)图层的属性发生更改时,它会询问其委托(如果图层正在支持视图,则始终是视图)以为该动画提供操作。然后,视图可以检查更改是否发生在动画块内部。如果更改发生在动画块内,则视图将返回具有正确持续时间,时序曲线等的动画。
但是,对于没有附加到图层的视图,没有代理可以询问。相反,该层继续寻找"动作" (动画的更通用术语),最终选择该图层类的默认动作。 CALayer上的the documentation for the -actionForKey:
方法概述了此行为。
默认操作几乎总是(路径的动画是一个例外)0.25秒长的基本动画。这是你看到的动画。图层实际上默认为其更改设置动画(它是一种禁用此功能的视图行为),因此您可以从动画块内的更改和动画块外部的形式看到此动画。
my objc.io article here的前三分之一更详细地解释了视图与图层之间的交互。我还有a blog post here,其中包括解释隐式动画和显式动画之间的区别。
上面解释了为什么您看到了这种行为。要修复"你可以去更高的抽象并使用视图而不是图层,或者你自己创建动画对象并将它们添加到图层(UIKit在视图级别进行的工作)。
答案 1 :(得分:1)
探索核心动画和堆栈溢出,您应该尝试使用2层来帮助您淡入和淡出。我试图解决类似的问题,下面的答案可以帮助我。
小代码示例:
此代码基于this回答。
CALayer *parentLayer = [CALayer layer];
CALayer *animtingLayer = [CALayer layer];
//FADE IN
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.beginTime = CMTimeGetSeconds(img.startTime);
animation.duration = CMTimeGetSeconds(_timeline.transitionDuration);
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat:1.0f];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeBoth;
animation.additive = NO;
[parentLayer addAnimation:animation forKey:@"opacityIN"];
//FADE OUT
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.beginTime = CMTimeGetSeconds(CMTimeAdd(img.passTimeRange.start, img.passTimeRange.duration));
animation.duration = CMTimeGetSeconds(_timeline.transitionDuration);
animation.fromValue = [NSNumber numberWithFloat:1.0f];
animation.toValue = [NSNumber numberWithFloat:0.0f];
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeBoth;
animation.additive = NO;
[animtingLayer addAnimation:animation forKey:@"opacityOUT"];
[parentLayer addSublayer:animtingLayer];