Core Animation学习笔记—第三节Animating Layer Content

各位iOS开发大佬们好:
我是一名swift+swiftUI栈的iOS小白,目前还在上大三,最近准备实习,面试的过程中发现现在大公司很多还在用OC + UIKit的技术栈,OC我还在考虑要不要学,目前想先把UIKit学完,这是我在官网学习UIKit英文文档时摘录的本人认为的重点,如果你们也觉得对你们有用的话欢迎持续关注,我大概一天更一节,有事除外。格式什么的我也就不做了,翻译都是我自己翻译的,哪里不对欢迎在评论区指正,感谢各位大佬支持

今天2021年12月3日
这一章叫做Animating Layer Content

这章其实就是显式动画和隐式动画
隐式动画根据值的改变触发默认动画
显式动画可以人为配置比如速度啊,时间函数什么的
显式动画通过CABasicAnimation 对象配置,配置完成后调用layer的add:forkey:方法添加动画到layer上,配置时默认使用当前属性值,也可通过formValue为动画属性赋初始值
显式动画只是做一套动画,不改变值本身,动画结束后,被添加动画的属性值又回到之前的值,如果需要值也改变那么在动画结束后赋上完成时的值即可
如果向layer添加多个显式动画或改变多个属性值引发多个隐式动画,那么这些动画将会同时执行,
动画会在下个runloop中执行,并且当前线程必须持有一个执行动画的runloop
关键帧动画:指定路径,描出一些关键点,
Specifying Keyframe Values
The key frame values are the most important part of a keyframe animation. These values define the behavior of the animation over the course of its execution. The main way to specify keyframe values is as an array of objects but for values that contain a CGPoint data type (such as the layer’s anchorPoint and position properties), you can specify a CGPathRef data type instead.
When specifying an array of values, what you put into the array depends on the data type required by the property. You can add some objects to an array directly; however, some objects must be cast to id before being added, and all scalar types or structs must be wrapped by an object. For example:
For properties that take a CGRect (such as the bounds and frame properties), wrap each rectangle in an NSValue object.
For the layer’s transform property, wrap each CATransform3D matrix in an NSValue object. Animating this property causes the keyframe animation to apply each transform matrix to the layer in turn.
For the borderColor property, cast each CGColorRef data type to the type id before adding it to the array.
For properties that take a CGFloat value, wrap each value in an NSNumber object before adding it to the array.
When animating the layer’s contents property, specify an array of CGImageRef data types.
For properties that take a CGPoint data type, you can create an array of points (wrapped in NSValue objects) or you can use a CGPathRef object to specify the path to follow. When you specify an array of points, the keyframe animation object draws a straight line between each successive point and follows that path. When you specify a CGPathRef object, the animation starts at the beginning point of the path and follows its outline, including along any curved surfaces. You can use either an open or closed path.
关键帧值定义了整个动画过程的行为,主要方式就是放在一个对象的数组中,如果对象是CGPoint类型,可以坐进CGPathRef里面
all scalar types or structs must be wrapped by an object
所有标量类型或结构都必须由对象包装
For properties that take a CGRect (such as the bounds and frame properties), wrap each rectangle in an NSValue object.
For the layer’s transform property, wrap each CATransform3D matrix in an NSValue object. Animating this property causes the keyframe animation to apply each transform matrix to the layer in turn.
For the borderColor property, cast each CGColorRef data type to the type id before adding it to the array.
For properties that take a CGFloat value, wrap each value in an NSNumber object before adding it to the array.
When animating the layer’s contents property, specify an array of CGImageRef data types.
When you specify an array of points, the keyframe animation object draws a straight line between each successive point and follows that path. When you specify a CGPathRef object, the animation starts at the beginning point of the path and follows its outline, including along any curved surfaces. You can use either an open or closed path.
如果指定的是封装为NSValue的数组中,那么动画将会在各个点之间连直线,如果是CGPathRef对象的话,会沿着路径进行,可以绘制出曲线路径

The calculationMode property defines the algorithm to use in calculating the animation timing. The value of this property affects how the other timing-related properties are used. 
Linear and cubic animations—that is, animations where the calculationMode property is set to kCAAnimationLinear or kCAAnimationCubic—use the provided timing information to generate the animation. These modes give you the maximum control over the animation timing. 
Paced animations—that is, animations where the calculationMode property is set to kCAAnimationPaced or kCAAnimationCubicPaced—do not rely on the external timing values provided by the keyTimes or timingFunctions properties. Instead, timing values are calculated implicitly to provide the animation with a constant velocity.
Discrete animations—that is, animations where the calculationMode property is set to kCAAnimationDiscrete—cause the animated property to jump from one keyframe value to the next without any interpolation. This calculation mode uses the values in the keyTimes property but ignores the timingFunctions property
The keyTimes property specifies time markers at which to apply each keyframe value. This property is used only if the calculation mode is set to kCAAnimationLinear, kCAAnimationDiscrete, or kCAAnimationCubic. It is not used for paced animations.
The timingFunctions property specifies the timing curves to use for each keyframe segment. (This property replaces the inherited timingFunction property.)

If you want to handle the animation timing yourself, use the kCAAnimationLinear or kCAAnimationCubic mode and the keyTimes and timingFunctions properties. The keyTimes defines the points in time at which to apply each keyframe value. The timing for all intermediate values is controlled by the timing functions, which allow you to apply ease-in or ease-out curves to each segment. If you do not specify any timing functions, the timing is linear.
指定时间函数和节奏的方法
calculationMode 属性定义了计算动画时间的算法,其值会影响其他跟时间有关的属性的用法
将其赋值为kCAAnimationLinear或kCAAnimationCubic的动画为线性和立方体动画————使用提供的计时信息生成动画。这些模式可以最大程度地控制动画计时。
将其赋值为kCAAnimationPaced或kCAAnimationCubicPaced的动画为节奏动画——不依赖于keyTimes或timeFunctions属性提供的外部定时值。计时值是隐式计算的,以便为动画提供恒定的速度。
将其为kCAAnimationDiscrete的动画为离散动画
——使动画属性在没有任何插值的情况下从一个关键帧值跳转到下一个关键帧值。此计算模式使用keyTimes属性中的值,但忽略了timeFunctions属性
keyTimes属性指定应用每个关键帧值的时间标记。仅当计算模式设置为kCAAnimationLinear、kCAAnimationDiscrete或kCAAnimationCubic时,才会使用此属性。它不用于节奏动画。
时序函数属性指定每个关键帧段使用的时序曲线。(此属性取代了继承的计时功能属性。)

移除正在运行的显式动画
To remove a single animation object from the layer, call the layer’s removeAnimationForKey: method to remove your animation object. This method uses the key that was passed to the addAnimation:forKey: method to identify the animation. The key you specify must not be nil.
To remove all animation objects from the layer, call the layer’s removeAllAnimations method. This method removes all ongoing animations immediately and redraws the layer using its current state information.
移除单个用removeAnimationForKey: ,移除全部用removeAllAnimations
不能移除隐式动画
组动画
为多个动画实现相同配置
更先进的办法是用transaction对象,后天第五节会更到那部分内容,

检测动画状态便于在动画的任意时刻触发其他行为
Add a completion block to the current transaction using the setCompletionBlock: method. When all of the animations in the transaction finish, the transaction executes your completion block.
Assign a delegate to your CAAnimation object and implement the animationDidStart: and animationDidStop:finished: delegate methods.

If you want to chain two animations together so that one starts when the other finishes, do not use animation notifications. Instead, use the beginTime property of your animation objects to start each one at the desired time. To chain two animations together, set the start time of the second animation to the end time of the first animation.
连接两个动画用begintime更好

iOS上的view底层都有layer,也没啥好说的,主要记一下osx上的
OS X上动layer的话可能造成view和layer不同步或其他不可预知的后果
,绝对不能动以下属性
anchorPoint
bounds
compositingFilter
filters
frame
geometryFlipped
hidden
position
shadowColor
shadowOffset
shadowOpacity
shadowRadius
transform
The preceding restrictions do not apply to layer-hosting views. If you created the layer object and associated it with a view manually, you are responsible for modifying the properties of that layer and keeping the corresponding view object in sync.
上述限制不适用于层托管视图。如果创建了图层对象并将其手动与视图关联,则有责任修改该图层的属性并使相应的视图对象保持同步。

AppKit disables implicit animations for its layer-backed views by default. The view’s animator proxy object reenables implicit animations automatically for you. If you want to animate layer properties directly, you can also programmatically reenable implicit animations by changing the allowsImplicitAnimation property of the current NSAnimationContext object to YES. Again, you should do this only for animatable properties that are not in the preceding list.
默认情况下,AppKit默认为有layer的view禁了隐式动画。视图的动画代理对象会自动为您重新启用隐式动画。如果您想直接为图层属性添加动画效果,您也可以通过将当前NSAnimationContext对象的 allowImplicitAnimation属性更改为YES,以编程方式重新启用隐式动画。同样,您应该只对不在上一个列表中的可动画属性进行此操作。
Remember to Update View Constraints as Part of Your Animation
If you are using constraint-based layout rules to manage the position of your views, you must remove any constraints that might interfere with an animation as part of configuring that animation. Constraints affect any changes you make to the position or size of a view. They also affect the relationships between the view and its child views. If you are animating changes to any of those items, you can remove the constraints, make the change, and then apply whatever new constraints are needed.
如果view是有限制的,那么动画实现是需要考虑到这些限制

猜你喜欢

转载自blog.csdn.net/Programmer_Roy/article/details/121662122