Core Animation - 图层行为

本文深入探讨了UIKit中隐式动画的工作原理及其实现方式,包括CALayer如何检测动画行为,以及UIKit为何会禁用隐式动画导致颜色跳变的现象。此外,还介绍了如何在UIView图层上手动实现动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面我们是对Layer层进行的动画,现在我们对UIView关联的图层进行同样的动画,一样的代码会发现,对UIView关联的图层动画平滑过渡的效果消失了,颜色直接跳变,那也就是说UIKit直接禁止了隐式动画。
先说下隐式动画的实现原理:

  1. 当使用CALayer的属性时,图层首先检测它是否有委托并实现了CALayerDelegate中的actionForLayer:forKey方法。如果有委托的话,直接调用并返回结果。
  2. 当没有委托或者没有调用actionForLayer:forKey方法,图层接着检查包含属性名称对应行为映射的actions字典。
  3. 如果actions字典没有包含这个属性的话,就在style字典中接着搜索。
  4. 如果还是找不到对应的行为,就调用属性的默认行为-defaultActionForKey方法。
    通过以上我们可以知道,actionForKey方法要么返回空,要么返回CALayer协议对应的对象,然后拿这个值和先前的值做比较。很明显在UIView图层找不到对应的方法,所以UIKit就这么禁用了隐式动画,画面出现了跳变现象。
    在CALayer图层块中隐式动画如何关闭呢:
[CATransaction setDisableActions:YES];

所以在UIView图层想要实现动画就是要使用UIView的动画函数,或者继承UIView,并覆盖-actionForLayer:forKey:方法,或者直接创建一个显示的动画。

下面对单独的一个图层进行操作,不使用隐式动画,通过给backgroundColor设置一个自定义的action字典,使用CATransaction的实例,来实现推进过度。

- (void)viewDidLoad
  {
      [super viewDidLoad];
      //create sublayer
      self.colorLayer = [CALayer layer];
      self.colorLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
      self.colorLayer.backgroundColor = [UIColor blueColor].CGColor;
      //add a custom action
      CATransition *transition = [CATransition animation];
      transition.type = kCATransitionPush;
      transition.subtype = kCATransitionFromLeft;
      self.colorLayer.actions = @{@"backgroundColor": transition};
      //add it to our view
      [self.layerView.layer addSublayer:self.colorLayer];
}
  - (void)changeColor
  {
//randomize the layer background color
CGFloat red = arc4random() / (CGFloat)INT_MAX;
CGFloat green = arc4random() / (CGFloat)INT_MAX;
CGFloat blue = arc4random() / (CGFloat)INT_MAX;
self.colorLayer.backgroundColor = [UIColor colorWithRed:red green:green blue:blue alpha:1.0].CGColor];
}

这里用了CATransition的另外两个属性,transition.type和transition.subtype,transition.type是动画的类型,这里为推动过度的,transition.subtype设置了动画推动的起始方向是从左边开始的。运行后会发现新的替换颜色是从左边推进的动画。
这里写图片描述
代码地址就不放了,还是原来的项目,增加两个属性就行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CodingFire

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值