动画里关于 CALayer 的一些零碎知识点

重温了一下《IOS 7 Programming: Pushing the Limits》这本书,有许多零碎的知识点,记录一下,勉强算作是学习笔记吧。

CALayer

  • Part 1

动画的基本单元就是 UIView,它是非常重量级的对象,所以不能多用。但你又想让你的 UI 看起来更酷,那就需要使用 Core Animation 了。Core Animation 中最基础也最重要的部分就是CALayer

设置 CALayer 就是设置图层的 contents 属性。和 UIView 不一样,UIView 在屏幕上第一次出现是会对自身进行绘制,而 CALayer 则不会,除非你调用setNeedsDisplay 方法标记 UIView 为需要重绘的,否则 contents 属性永远不会被更新(即便它是 nil )。

CALayer 隐式为所有支持动画的属性添加动画,比如设置一个 layer 层从一个点到另外一个点时,它不是直接跳过去的,而是会有一个渐进的过度效果。看一下LayerAnimation
的代码可能会好一点,或者自己动手试一下。可以通过设置 [CATransation setDisableAction: YES]; 来禁用动作阻止此动画。

tips: 以下 API 可以设置一个 view 过渡到另外一个 view 时的效果,挺好看的。

[UIView transitionFromView:self.view toView:anotherView duration:1 options:UIViewAnimationOptionTransitionFlipFromRight completion:nil];

隐式动画能够完成的显式动画都能完成,常见的显式动画有 CABasicAnimation , 更高级一点的又 CAKeyframeAnimation ,后者可以利用路径或点序列实现动画,并为动画单独计时。关于这两个动画的使用和拓展可以看这篇文章。

另外推荐两个关于动画的专题文章,特别不错:

1)动画

2)ios-Core-Animation-Advanced-Techniques(翻译)

3) Animating the Drawing of a CGPath With CAShapeLayer,效果挺好的,可以看一下。

  • Part 2

动画中的一个常见问题就是麻烦的“闪回”(jump back)问题。错误如下:

    CABasicAnimation *fade;
    fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fade.duration = 1;
    fade.fromValue = @1.0;
    fade.toValue = @0.0;
    [circleLayer addAnimation:fade forKey:@"fade"];

这段代码会让圆圈淡出大约 1 秒钟,之后突然出现。要了解突然出现的原因,需要明了模型层表示层的区别。

模型层是由“真正” CALayer 对象的属性定义的。前面的代码没有任何地方修改 circleLayer 本身。相反,CAAnimation 创建了 circleLayer 的副本并对其进行修改,使其变成表示层。它们大致表示会在屏幕上显示什么内容。从技术上讲还存在一个渲染层,真正表示屏幕上要显示的内容,不过它是 Core Animation
内部的功能,你很少会遇到它。如果想深入学习图层树,看上面提到的 ios-Core-Animation-Advanced-Techniques 部分内容,阐述得很详细。

那么前面的代码发生了什么呢?CAAnimation 修改了表示层,表示层将被绘制到屏幕上,绘制完成后,所有的更改都会丢失并由模型层决定新状态。模型层没有改变,因此会恢复一开始的状态。解决办法是设置模型层,如下设置:

    <strong>circleLayer.opacity = 0;</strong>
    CABasicAnimation *fade;
    fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fade.duration = 1;
    fade.fromValue = @1.0;
    fade.toValue = @0.0;
    [circleLayer addAnimation:fade forKey:@"fade"];

有时它能正常工作,但有时 setOpacity: 中的隐式动画会与 animationWithKeyPath: 的显式动画冲突。最好的解决办法是在执行显式动画时关闭隐式动画:

    <strong>[CATransaction begin];
    [CATransaction setDisableActions:YES];</strong>
    circleLayer.opacity = 0;
    CABasicAnimation *fade;
    fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
    fade.duration = 1;
    fade.fromValue = @1.0;
    fade.toValue = @0.0;
    [circleLayer addAnimation:fade forKey:@"fade"];
    <strong>[CATransaction commit];</strong>

-----------------------------------------------------voice------------------------------------------------------------------------------------------------------

important note:有人推荐设置 removedOnCompletion 为 NO、fillMode 为 kCAFillModeBoth。这并不是好的解决办法。它本质上会让动画一直执行,这意味着模型永远不更新。如果你想要获得属性的值,得到的只是模型的值,而不是真正绘制在屏幕上的内容。如果之后试着对属性应用隐式动画,它不会正常工作,因为 CAAnimation
仍然在运行。如果你通过其他名称相同的动画进行替换来移除动画,那么调用 removeAnimationForKey: 或 removeAllAnimations 后就会获取旧值。而且这样会浪费内存。

-------------------------------------------------------------------------------------------------------------------------------------------------------------------

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-14 22:00:43

动画里关于 CALayer 的一些零碎知识点的相关文章

JAVA零碎知识点

总结的JAVA零碎知识点 学习和工作中总会有一些零碎的知识点,可能不经常用到或者以前不熟知,在此记录一下. 一.有关Lamda表达式 Lamda表达式是1.8新增特性,所以使用前请确定项目JDK版本是否支持. Lamda主要解决匿名内部类和函数的啰嗦语句问题,比如曾经的Jframe的Jbutton监听事件addActionListener JButton jb = new JButton("click"); jb.addActionListener(new ActionListener

iOS开发零碎知识点

记录一些常用和不常用的iOS知识点,防止遗忘丢失.(来源为收集自己项目中用到的或者整理看到博客中的知识点),如有错误,欢迎大家批评指正:如有好的知识点,也欢迎大家联系我,添加上去.谢谢! 一.调用代码使APP进入后台,达到点击Home键的效果.(私有API) [[UIApplication sharedApplication] performSelector:@selector(suspend)]; suspend的英文意思有:暂停; 悬; 挂; 延缓; 二.带有中文的URL处理. 大概举个例子

iOS核心动画高级技巧之CALayer(一)

UIView和CALayer的关系 在iOS中一个UIView对应着一个CALayer,视图的职责就是创建并管理这个图层,以确保当子视图在层级关系中添加或者被移除的时候,他们关联的图层也同样对应在层级关系树当中有相同的操作.实际上这些背后关联的图层才是真正用来在屏幕上显示和做动画,UIView仅仅是对它的一个封装,提供了一些iOS类似于处理触摸的具体功能,以及Core Animation底层方法的高级接口.(CALayer并不能响应事件,它提供了几个能判断一个触点时候再图层的范围之内) CALa

零碎知识点整理

一.常用用UIImage加载图像的方法有: 1.用imageNamed函数(适用于图片频繁使用场景) [UIImage imageNamed:ImageName]; 用imageNamed的方式加载时,系统会把图像Cache到内存.如果图像比较大,或者图像比较多,用这种方式会消耗很大的内存,而且释放图像的 内存是一件相对来说比较麻烦的事情.例如:如果利用imageNamed的方式加载图像到一个动态数组NSMutableArray,然后将将数组赋予一 个UIView的对象的animationIma

CAKeyframeAnimation path 绘制动画 和 《CALayer 自定义属性绘制动画》 的比较

在<CALayer 自定义属性绘制动画>中讲解通过CALayer 自定义动画属性绘制圆,使用CABasicAnimation添加绘制动画,下面通过CGPath绘制圆使用CAKeyframeAnimation添加绘制动画 UIBezierPath *path = [UIBezierPathbezierPathWithArcCenter:CGPointMake(20, 20) radius:20 startAngle:0 endAngle:2*M_PIclockwise:0]; CAKeyfram

Lottie 动画里有图片怎么办?设计师小姐姐也能帮你减少开发量!

一.序 Hi,大家好,我是承香墨影! Lottie 是 Airbnb 开源的一套跨平台的完整解决方案,设计师只需要使用 After Effectes (之后简称 AE)设计出动画之后,使用 Lottic 提供的 Bodymovin 插件将设计好的动画导出成 JSON 格式,就可以直接运用在 iOS.Android 和 React Native之上,无需关心中间的实现细节. 这样,对于不同的工作角色来说,Lottie 带来的都是更简洁的工作流.开发小哥哥不再担心动画实现困难,设计师小姐姐也不需要担

MVC零碎知识点记录

--------------------------------------------------------------------------------------------------------- 在html文件中嵌入服务器代码: <div> <!--单行(Single Line)标记--> @{ var name = "Slark";} @{ Response.Write("Single Line : Name is" + n

Java中一些零碎知识点集合(后续补充)

-----------------------------------关于封装------------------------------------- 封装原则 将不需要对外提供的内容隐藏起来. 把属性隐藏,提供公共方法对其进行访问.之所以对某些信息进行封装然后提供公共接口让外人进行访问,是因为可以对访问操作方式进行控制,来规范用户输入的数据,限制不合理信息,提高代码的健壮性. -----------------------------------构造函数方法-----------------

实现UIView的无限旋转动画(非CALayer动画)

效果: 素材: 源码: // // ViewController.m // Animation // // Created by YouXianMing on 15/2/5. // Copyright (c) 2015年 YouXianMing. All rights reserved. // #import "ViewController.h" @interface ViewController () @property (nonatomic, strong) UIImageView