每个 UIView 内部都有一个 CALayer 在背后提供内容的绘制和显示,并且 UIView 的尺寸样式都由内部的 Layer 所提供。两者都有树状层级结构,layer 内部有 SubLayers,View 内部有 SubViews.但是 Layer 比 View 多了个AnchorPoint
在 View显示的时候,UIView 做为 Layer 的CALayerDelegate,View 的显示内容取决于内部的 CALayer 的 display
CALayer 是默认修改属性支持隐式动画的,在给 UIView 的 Layer 做动画的时候,View 作为 Layer 的代理,Layer 通过 actionForLayer:forKey:向 View请求相应的action(动画行为)
layer 内部维护着三分layer tree,分别是 presentLayer Tree(动画树),modeLayer Tree(模型树), Render Tree (渲染树),在做 iOS动画的时候,我们修改动画的属性,在动画的其实是 Layer 的 presentLayer的属性值,而最终展示在界面上的其实是提供 View的modelLayer
两者最明显的区别是 View可以接受并处理事件,而 Layer 不可以
隐式动画与显示动画:
隐式动画
不需要初始化任何类,系统自己处理的动画属性
粗浅的可以理解为,系统默认,自带的效果
这其实就是所谓的隐式动画。之所以叫隐式是因为我们并没有指定任何动画的类 型。我们仅仅改变了一个属性,然后Core Animation来决定如何并且何时去做动 画。Core Animaiton同样支持显式动画,
核心动画的隐式动画模型假定所有动画图层属性的变化应该是渐进的和异步的。
动态的动画场景可以在没有显式的动画图层时候实现。
改变动画显示的图层的属性将会导致图层隐式把旧值动画显示为新值,虽然动画是持续的,但是设置新的目标值会导致图层从当前状态动画过度到新的目标值
OrderSearchVC *search = [[OrderSearchVC alloc] init];
[self.navigationController pushViewController:search animated:YES];
根据我粗浅的理解,「隐式动画」中的所谓「隐式」,是相对于「显式动画」中的显式而言的。
实现显式动画时,往往会创建一个动画对象,譬如CAAnimation、CABasicAnimation、CAKeyframeAnimation,然后通过CALayer#addAnimation(_:forKey:)方法该动画对象绑定到layer中,
显式动画
核心动画同事提供了一个显示动画模型。该显式动画模型需要你创建一个动画对象,并设置开始值和结束的值,显示动画不会开始执行,直到你把该动画应用到某个图层上面
CABasicAnimation *opAnim = [CABasicAnimation animationWithKeyPath:@opacity];
opAnim.duration = 1.0;
opAnim.fromValue = [NSNumber numberWithFloat:0.1];
opAnim.toValue= [NSNumber numberWithFloat:1.0];
opAnim.repeatCount = 1;
[view.layer addAnimation:opAnim forKey:@animateOpacity];
iOS 动画会改变frame吗?
在iOS开发中,动画本身通常不会直接改变视图的frame
属性,但动画的效果会让视图看起来像是在移动、缩放、旋转或改变透明度等。这种视觉上的变化是通过改变视图层的属性(如CALayer
的position
、bounds
、transform
等)来实现的,而不是直接修改frame
。
帧(Frame)与层(Layer)
-
帧(Frame):
UIView
的frame
属性定义了视图在其父视图坐标系统中的位置和大小。这是一个矩形,通常用CGRect
结构体表示,包含origin
(原点,即左上角的位置)和size
(尺寸)。 -
层(Layer):
UIView
的底层是由CALayer
实现的。CALayer
提供了对视图内容渲染的底层支持,包括位置、大小、透明度、边框、阴影等属性的管理。动画效果通常是通过修改CALayer
的属性来实现的。
动画与frame
动画执行:当你对视图应用动画(如使用
UIView
的动画块或Core Animation
框架)时,你通常会修改与动画相关的层属性(如position
、bounds
、transform
等)。这些变化会立即反映在视觉上,但frame
属性可能不会自动更新以反映这些变化。frame
与bounds
/center
:frame
是相对于父视图的,而bounds
和center
是相对于视图自身的。当你通过动画改变视图的位置时(例如,通过修改center
或position
),虽然视图在屏幕上移动了,但其frame
的origin
可能并没有立即更新(因为它仍然表示在父视图坐标系中的原始位置)。但是,如果你通过修改frame
本身来移动视图(而不是通过动画),则frame
会立即更新,但这种情况下不会有动画效果。动画完成后的状态:如果你通过动画改变了视图的位置或大小,并希望这些变化在动画完成后保持下来,你需要确保在动画开始前或在动画的完成回调中手动更新
frame
属性(如果需要的话)。不过,在很多情况下,由于CALayer
的属性(如position
)已经改变,所以frame
可能会间接地“看起来”已经更新,即使你没有显式地设置它。
结论
动画本身不会直接改变frame
,但动画的效果可能会让视图看起来像是改变了位置或大小。如果你需要确保动画完成后的状态与动画过程中的状态一致,你可能需要手动更新frame
或其他相关属性。然而,在大多数情况下,通过修改CALayer
的属性(如position
、bounds
、transform
)来实现动画效果就足够了,因为iOS的视图系统会在底层处理好这些变化与frame
之间的关系。
作者:不简单的风度
链接:https://www.jianshu.com/p/ed40da9303b1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。