Ios 在层备份视图上使用核心动画
在中,有一段关于Ios 在层备份视图上使用核心动画,ios,objective-c,animation,Ios,Objective C,Animation,在中,有一段关于如何设置图层背景视图的动画,它说: 如果要使用核心动画类来启动动画,则必须从基于视图的动画块内部发出所有核心动画调用。UIView类默认情况下禁用层动画,但在动画块内重新启用它们。因此,在动画块外部所做的任何更改都不会设置动画 myView.layer.opacity = 0.0; 还有一个例子: [UIView animateWithDuration:1.0 animations:^{ // Change the opacity implicitly. my
如何设置图层背景视图的动画,它说:
如果要使用核心动画类来启动动画,则必须从基于视图的动画块内部发出所有核心动画调用。UIView类默认情况下禁用层动画,但在动画块内重新启用它们。因此,在动画块外部所做的任何更改都不会设置动画
myView.layer.opacity = 0.0;
还有一个例子:
[UIView animateWithDuration:1.0 animations:^{
// Change the opacity implicitly.
myView.layer.opacity = 0.0;
// Change the position explicitly.
CABasicAnimation* theAnim = [CABasicAnimation animationWithKeyPath:@"position"];
theAnim.fromValue = [NSValue valueWithCGPoint:myView.layer.position];
theAnim.toValue = [NSValue valueWithCGPoint:myNewPosition];
theAnim.duration = 3.0;
[myView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
}];
在我看来,这说明如果我不从基于视图的动画块内部发出核心动画调用,就不会有动画
但是,如果我直接添加核心动画调用,而不添加基于视图的动画块,效果似乎是一样的
我遗漏了什么吗?我将用一个简单的演示(示例)来解释它。
在视图控制器中添加以下代码。(不要忘记导入QuartzCore)
请注意,在ToucesBegind方法中没有UIVIew动画块。
当您运行应用程序并单击屏幕时,图层的不透明度将设置动画。这是因为默认情况下,这些图层都可以设置动画。默认情况下,图层的所有属性都可以设置动画
现在考虑层备份视图的情况。
将代码更改为下面的代码
- (void)viewDidLoad
{
[super viewDidLoad];
view =[[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
[self.view addSubview:view];
view.backgroundColor =[UIColor greenColor];
// layer = [CALayer layer];
// layer.frame =CGRectMake(0, 0, 50, 50);
// layer.backgroundColor =[UIColor redColor].CGColor;
// [view.layer addSublayer:layer];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
view.layer.opacity =0.0;
// layer.frame =CGRectMake(70, 70, 50, 50);
}
您可能认为这也将使其视图具有动画效果。但这不会发生。因为默认情况下,层备份视图不具有动画效果。
要实现这些动画,必须在UIView动画块中显式嵌入代码。如下所示
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[UIView animateWithDuration:2.0 animations:^{
view.layer.opacity =0.0;
}];
// layer.frame =CGRectMake(70, 70, 50, 50);
}
这就说明,
UIView类(显然是层备份的)默认情况下禁用层动画,但在动画块内重新启用层动画。因此,在动画块外所做的任何更改都不会设置动画。嗯,我从未在视图动画块内使用过显式核心动画。文档似乎一点也不清楚。
可能意思是这样的,只是猜测:
如果要设置链接到视图的视图属性的动画
备份层您应该将它们包装到视图动画块中。在
视图的图层如果您尝试更改图层不透明度,则这不是
已设置动画,但如果包裹到视图动画块中,则为。
在代码段中,直接创建基本动画,从而显式创建动画。文档可能只是想指出视图和层之间的差异。在后面的动画中,大多数属性都是隐式的。
如果你这样写的话,你就能看到区别:
[UIView animateWithDuration:1.0 animations:^{
// Change the opacity implicitly.
myView.layer.opacity = 0.0;
}];
这将是动画
myView.layer.opacity = 0.0;
这将不会设置动画
// Change the position explicitly.
CABasicAnimation* theAnim = [CABasicAnimation animationWithKeyPath:@"position"];
theAnim.fromValue = [NSValue valueWithCGPoint:myView.layer.position];
theAnim.toValue = [NSValue valueWithCGPoint:myNewPosition];
theAnim.duration = 3.0;
[myView.layer addAnimation:theAnim forKey:@"AnimateFrame"];
这将设置动画。tl;dr:本文档仅涉及隐式动画。显式动画在动画块之外工作良好
myView.layer.opacity = 0.0;
我对文件的解释
文件中引用的简化版本类似于(我解释一下):
UIView已禁用隐式动画(动画块内除外)。如果要执行隐式层动画,必须在动画块内执行
什么是隐式动画?它们是如何工作的?
隐式动画是指当独立层的可设置动画的特性更改时发生的情况。例如,如果创建一个层并更改其位置,它将设置为新位置的动画。默认情况下,许多图层特性都具有此行为
事情是这样的:
事务由系统启动(我们不做任何事情)
属性的值已更改
图层将查找该属性的操作
在某个时刻,事务被提交(我们不做任何事情)
已应用找到的操作
请注意,上面没有提到动画,而是提到了“动作”一词。此上下文中的操作是指实现CAAction
协议的对象。它很可能是某个CAAnimation子类(比如CABasicAnimation、CAKeyframeAnimation或cattransition),但它是为处理符合该协议的任何内容而构建的
它如何知道要采取什么“行动”?
通过调用层上的actionForKey:
来查找该属性的操作。此操作的默认实现按以下顺序查找操作:
此搜索按以下顺序进行(参考:)
如果层有一个委托,并且该委托实现了访问层的Filters方法,则层调用该方法。代表必须执行以下操作之一:
- 返回给定键的操作对象
- 如果未处理该操作,则返回
nil
- 如果对象不处理操作,则返回
NSNull
对象,并且应终止搜索
该层在层的操作
字典中查找
该层在样式
字典中查找包含键的操作字典
该层调用其defaultActionForKey:
方法来查找任何类定义的操作
该层查找由核心动画定义的任何隐式动作
UIView在做什么?
对于作为背景视图的图层,视图可以启用或禁用操作。对于正常情况(动画块外部),视图通过返回[NSNull null]
禁用隐式动画,这意味着:
它不处理该操作,应终止搜索
但是,在动画块内,视图返回真实动作。这可以通过在动画块内外手动调用actionForLayer:forKey:
来轻松验证。它还可能返回nil
,这将导致层继续寻找动作,最终以隐式动作(如果有的话)i结束
myView.backgroundColor = [UIColor redColor]; // animates :)
myLayer.backGroundColor = [[UIColor redColor] CGColor]; // animates :)
myView.layer.backGroundColor = [[UIColor redColor] CGColor]; // animates :)
[myView.layer addAnimation:myAnimation forKey:@"myKey"]; // animates :)