代码编织梦想

1. 概述

上文简单讲述了CALayer的概念以及一些属性,针对于Layer,除了其展示样式,我们更注重它的动画,本篇文章及本专栏的后续文章将围绕Layer的核心动画进行探究。

本文首先看一下CALayer的基础动画类CABasicAnimation以及CATransaction的使用。

2.  CALayer基础动画

CALayer基础动画类为CABasicAnimation,看一下官方的定义:

An object that provides basic, single-keyframe animation capabilities for a layer property.

一个能够给Layer提供基础的单个关键帧动画能力的对象。

2.1 常用属性及方法

常用方法及属性见下表:

属性及方法类型说明
init(keyPath: String?)/初始化方法
fromValueAny?动画执行初始值
toValueAny?动画执行结束值
byValueAny?动画执行的结束值与初始值的差值
keyPathString?指定执行动画的key path
isRemovedOnCompletionBool动画执行结束后是否从目标图层中移除。设置为false解决动画恢复到初始位置的问题。
fillModeCAMediaTimingFillMode

removed:默认值,动画开始前和结束后,动画对图层都没有影响,图层依然保持初始值。

forwards:动画结束后保持最终的可见状态。

backwards:动画开始前,只要加入动画,图层就会处于动画的初始状态,即第一帧动画。

both:综合了forwards和backwards两种功能,动画加入图层到真正执行动画的时间段里,图层保持动画初始状态;动画结束之后保持动画最终状态

durationCFTimeInterval动画执行时长
repeatCountFloat动画执行次数
repeatDurationCFTimeInterval动画多久后执行一次。

关于fillMode属性更多解释,请详见iOS CAMediaTiming协议理解

创建动画的时候可通过init(keyPath: String?)方法实例化一个对象,并指定一个属性的keyPath用于动画。

可以将一个标量属性(有具体的数值)添加动画,比如不同明度(opacity),将其值从0设置到1,代码如下:

    override func viewDidLoad() {
        super.viewDidLoad()
        layer.frame = CGRect(x: 20, y: 60, width: 100, height: 100)
        layer.backgroundColor = UIColor.red.cgColor
        self.view.layer.addSublayer(layer)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let animation = CABasicAnimation(keyPath: "opacity")
        animation.fromValue = 0
        animation.toValue = 1
        animation.duration = 2
        animation.isRemovedOnCompletion = false
        animation.fillMode = .forwards
        layer.add(animation, forKey: nil)
    }

上面创建了一个红色的layer,并将其添加到了当前view的layer中,当点击屏幕的时候,修改红色layer的opacity。

一些非标量属性,比如背景色(backgroundColor),其值变化也可以加入动画,代码如下,重复代码不在提现:

let animation = CABasicAnimation(keyPath: "backgroundColor")
animation.fromValue = UIColor.red.cgColor
animation.toValue = UIColor.blue.cgColor

还给可给一些多值的属性添加动画,比如位置信息(position),代码如下:

let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = [0, 0]
animation.toValue = [100, 100]

除了以上,还可以给某个属性的里面的某个值添加动画,例如:

let animation = CABasicAnimation(keyPath: "transform.scale.x")
animation.fromValue = 1
animation.toValue = 2

2.2 常用Key Paths

以上便是一些基础动画的创建,至于哪些keyPath可以执行动画,具体如下:

CATransform3D Key Paths

Key Path

Description

transform.rotation.x

设置一个沿着x轴旋转的弧度值。 关于π,Swift 3.0以后请使用Doubl.pi

transform.rotation.y

设置一个沿着y轴旋转的弧度值。

transform.rotation.z

设置一个沿着z轴旋转的弧度值。

transform.rotation

设置一个沿着z轴旋转的弧度值,同transform.rotation.z。

transform.scale.x

设置一个沿着x轴放缩的比例因子。

transform.scale.y

设置一个沿着y轴放缩的比例因子。

transform.scale.z

设置一个沿着z轴放缩的比例因子。

transform.scale

设置一个整体放缩的比例因子。

transform.translation.x

设置一个沿着x轴移动的值。

transform.translation.y

设置一个沿着y轴移动的值。

transform.translation.z

设置一个沿着z轴移动的值。

transform.translation

设置一个结构体类型的值,例如CGSize,CGPoint,其值表示沿着x轴和y轴移动的数值。

CGPoint Key Paths

Key Path

Description

position.x

设置一个中心点沿着x轴移动的值。

position.y

设置一个中心点沿着y轴移动的值。

CGSize Key Paths

Key Path

Description

bounds.size.width

设置一个宽度变换的值。

bounds.size.height

设置一个高度变换的值。

3.  CATransaction

CATransaction是将Layer tree多个操作批处理为渲染树的原子更新的核心动画机制。对Layer tree的每个修改都必须是CATransaction的一部分。支持嵌套CATransaction。

Core Animation支持两种类型的CATransaction:implicit transactions(隐式)和explicit transactions(显式)。

implicit transactions在没有活动transactions的线程修改layer tree的时候自动创建,并在线程runloop下一次迭代的时候自动提交。

explicit transactions则是在修改layer tree之前向CATransaction类发送begin()消息,修改后发送commit()消息时时候触发。

常用类方法如下表:

类方法说明
class func begin()在当前线程创建一个transaction。
class func commit()提交当前transaction的所有修改。
class func flush()刷新任何存在的隐式transaction.
class func animationDuration() -> CFTimeInterval返回在transaction组中所有动画的执行时间。
class func setAnimationDuration(CFTimeInterval)设置transaction组中所有动画的执行时间。
class func completionBlock() -> (() -> Void)?返回动画结束后的block对象。
class func setCompletionBlock((() -> Void)?)设置动画结束后的block对象。

关于隐式动画,我们不需要添加额外的代码,系统会自己处理,比如在改变backgroundColor的时候,颜色会从一个到另一个颜色渐变过去,系统的动画时间为0.25秒。

至于显示动画,则需要我们手动添加代码了。

先看一段简单的代码,将一个Layer的的size变成原来的两倍,并改变其背景色。

    func transactionAnimation() {
        CATransaction.begin()
        let transform = CATransform3DScale(layer.transform, 2, 2, 2)
        layer.transform = transform
        CATransaction.setAnimationDuration(2)
        CATransaction.setCompletionBlock {
            self.layer.backgroundColor = UIColor.blue.cgColor
        }
        CATransaction.commit()
    }

下面看一个显示的嵌套CATransaction,Layer从不透明到透明,然后移除,期间size变为原来的3倍。

    func transactionNestedAnimation() {
        // Outer transaction animates `opacity` to 0 over 2 seconds
        CATransaction.begin()
        CATransaction.setAnimationDuration(2)
        layer.opacity = 0
        CATransaction.setCompletionBlock {
            self.layer.removeFromSuperlayer()
        }
             
        // Inner transaction animates scale to (3, 3, 3) over 1 second
        CATransaction.begin()
        CATransaction.setAnimationDuration(2)
        layer.transform = CATransform3DMakeScale(3, 3, 3)
        CATransaction.commit() // Commits inner transaction
        CATransaction.commit() // Commits outer transaction
    }

4. 总结

本文主要讲述了CABasicAnimation以及CATransaction两种动画,作为基础动画,用起来并不难,文中也列举了常用的一些方法和属性等。

文中如有不正确的地方,还请路过的朋友指正。

 

本篇文章出自https://blog.csdn.net/guoyongming925的博客,如需转载,请标明出处。

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接: https://blog.csdn.net/guoyongming925/article/details/111093444

Android 事件分发机制抽象--钓钩模型-爱代码爱编程

用户体验小姐姐巧妙地利用有限的手机屏幕空间,完美地设计出简单实用的交互功能,如果多问一句 “怎么做到的” ? 答案必须是从事件分发机制的高超运用说起。 在我 Android 应用业务开发职业生涯中,接触到最多的也正是如何运用事件分发机制和自定义控件,堆砌出一幅幅可交互的精致业务功能画面。下图是我分别在手机百度 App 和美团 App 上研发的“列

好家伙,微信能设置2个头像了!-爱代码爱编程

上一期为大家分享了一个微信小技能,改昵称。 没想到反响很不错, 小伙伴玩得不亦乐乎,留言区变成一片彩色的海洋, 既然大家对这类微信小技能如此感兴趣。 今天,再给小伙伴分享一个微信玩法——双头像。 效果如下图所示↓ ,安卓iOS都支持哦。 小图查看的不太清晰,给你们实际操作一遍仔细瞧瞧。 制作步骤非常简单,进入工具后,顶部显示的是

微软将开始强制部分用户升级 Windows 10 | 新闻拍一拍-爱代码爱编程

  导读:更多:• WPS 进入全国计算机二级考试 • Brave 被迫剔除了 iPad/iOS 版本的广告奖励项目 本文字数:935,阅读时长大约:1分钟 作者:硬核老王 微软将开始强制部分用户升级 Windows 10 在微软宣布结束对 Windows 10 版本 1903 的支持之后,从本月开始,微软将开始强制部分用户升级

Flutter iOS风格中Widget内容滑到了顶部导航栏后面与其重叠-爱代码爱编程

Flutter 开发问题点一览 Flutter iOS风格中Widget内容滑到了顶部导航栏后面与其重叠Flutter iOS风格文本输入框CupertinoTextField光标在Android中未与提示文本对齐 文章目录 Flutter 开发问题点一览1. 问题描述2. 原因、对策3. 源码分析 1. 问题描述 Flutter在iOS风格

ios 升级后,滚轮选择的时间控件失效 UIDatePicker-爱代码爱编程

变成这个样子了     2.如果使用以前的样式 datepicker.preferredDatePickerStyle = .wheels 不知道是不是苹果的bug 宽高都不对 let datepicker = UIDatePicker(frame: CGRect(x: 0, y: 100, width: self.view.frame

IOS UIWindow 和 UIScreen-爱代码爱编程

通常UIWindow 与 UIScreen 是配合使用的。当我们想自定义window对象或者获取硬件屏幕大小必定会用到 UIWindow 和 UIScreen UIWindow 一个APP只有一个UIWindow 对象,表示当前窗口对象。UIWindow 继承于 UIView。 通常使用Window 自定义根节点的 UIViewControl

Swift 如何生成随机数-爱代码爱编程

1.生成Int类型随机数 var numberOne: Int = Int(arc4random()) print(numberOne) 结果: 3628967563 说明:arc4random()直接返回UInt32类型数据 2.生成Double类型随机数 var numberFour: Double = drand48() print(

关于iOS系统你知道多少???-爱代码爱编程

首先来说下ios的历史吧!!! iOS系统诞生于2007年1月1日的Macworld上,当天公布了IOS的初代系统,当时它的名字是iPhone OS X,同时颠覆手机行业的iPhone也横空出世了,它创新的多点触控操作以及极简的用户体验都让全球消费者为之疯狂,3.5英寸的480X320分辨率的大屏幕也远远超过当时手机行业的平均配置,单Home键让 当时标配

iOS上获取崩溃日志的N+1种方法-爱代码爱编程

iOS上获取崩溃日志的N+1种方法 正常情况下,程序崩溃之后都会有崩溃日志保存在我们的手机里面,当崩溃的时候,我们可以通过如下几种方式找到我们的崩溃日志。  方法一:从本机隐私设置里面的里面导出来       当本机发生崩溃的时候,你可以从系统设置->隐私->分析与改进里面找到你当时的崩溃日志,通常,你的崩溃日志格式包含程序包名,时