版本记录
版本号 | 时间 |
---|---|
V1.0 | 2018.01.23 |
前言
在苹果的API文档中,有很多属性和方法我们用的不是很多,所以很容易忽略和出错,下面我就用这一个专题专门说一些不常用的API接口,下面开始。感兴趣的可以参考前面几篇文章。
1. 容易忽略的那些小点总结 (一) —— UIView UIViewTintAdjustmentMode相关(一)
2. 容易忽略的那些小点总结 (二) —— CALayer相关(一)
3. 容易忽略的那些小点总结 (三) —— CALayer相关(二)
4. 容易忽略的那些小点总结 (四) —— CALayer相关(三)
5. 容易忽略的那些小点总结 (五) —— CALayer相关(四)
6. 容易忽略的那些小点总结 (六) —— CALayer相关(五)
7. 容易忽略的那些小点总结 (七) —— CALayer相关(六)
shadowPath
图层阴影的形状,可动画。
/* When non-null this path defines the outline used to construct the
* layer's shadow instead of using the layer's composited alpha
* channel. The path is rendered using the non-zero winding rule.
* Specifying the path explicitly using this property will usually
* improve rendering performance, as will sharing the same path
* reference across multiple layers. Upon assignment the path is copied.
* Defaults to null. Animatable. */
非空时,此路径定义用于构建图层阴影的轮廓,而不是使用图层的合成Alpha通道。 路径使用非零缠绕规则进行渲染。使用此属性明确指定路径通常会提高渲染性能,因为在多个图层之间共享相同的路径引用。 分配后,路径被复制。 缺省为null,可动画。
@property(nullable) CGPathRef shadowPath;
还有几点需要注意:
此属性的默认值为nil,这会导致图层使用标准的阴影形状。如果为此属性指定值,则图层将使用指定的路径而不是图层的合成Alpha通道来创建其阴影。您提供的路径定义了阴影的轮廓。它使用非零缠绕规则和当前的阴影颜色,不透明度和模糊半径进行填充。
与大多数动画属性不同,此属性(与所有
CGPathRef
动画属性一样)不支持隐式动画。但是,路径对象可以使用CAPropertyAnimation
的任何具体子类来动画。路径将作为on-line
点的线性混合进行插值;off-line
点可以非线性插值(以保持曲线导数的连续性)。如果两个路径的控制点或段数不同,则结果是不确定的。如果路径延伸到图层边界之外,则只有在正常的图层遮罩规则导致该图层时,才会自动被图层剪切。指定显式路径通常会提高渲染性能。
使用
Core Foundation retain/release
语义来保留此属性的值。即使属性声明似乎使用对象保留的默认分配语义事实发生此行为。您可以使用图层的阴影路径来创建特殊效果,例如模拟Pages中可用的阴影。
Listing 1
显示了将椭圆阴影添加到图层底部以模拟Pages Contact Shadow
效果所需的代码。
// Listing 1 Creating a contact shadow path
let layer = CALayer()
layer.frame = CGRect(x: 75, y: 75, width: 150, height: 150)
layer.backgroundColor = NSColor.darkGray.cgColor
layer.shadowColor = NSColor.gray.cgColor
layer.shadowRadius = 5
layer.shadowOpacity = 1
let contactShadowSize: CGFloat = 20
let shadowPath = CGPath(ellipseIn: CGRect(x: -contactShadowSize,
y: -contactShadowSize * 0.5,
width: layer.bounds.width + contactShadowSize * 2,
height: contactShadowSize),
transform: nil)
layer.shadowPath = shadowPath
-
Listing 2
显示了如何创建一个模拟Pages Curved Shadow
的路径。 路径的左侧,上侧和右侧是直线,底部是凹曲线,如图2所示。
// Listing 2 Creating a curved shadow path
let layer = CALayer()
layer.frame = CGRect(x: 75, y: 75, width: 150, height: 150)
layer.backgroundColor = NSColor.darkGray.cgColor
layer.shadowColor = NSColor.black.cgColor
layer.shadowRadius = 5
layer.shadowOpacity = 1
let shadowHeight: CGFloat = 10
let shadowPath = CGMutablePath()
shadowPath.move(to: CGPoint(x: layer.shadowRadius,
y: -shadowHeight))
shadowPath.addLine(to: CGPoint(x: layer.shadowRadius,
y: shadowHeight))
shadowPath.addLine(to: CGPoint(x: layer.bounds.width - layer.shadowRadius,
y: shadowHeight))
shadowPath.addLine(to: CGPoint(x: layer.bounds.width - layer.shadowRadius,
y: -shadowHeight))
shadowPath.addQuadCurve(to: CGPoint(x: layer.shadowRadius,
y: -shadowHeight),
control: CGPoint(x: layer.bounds.width / 2,
y: shadowHeight))
layer.shadowPath = shadowPath
preferredFrameSize
返回在其父层坐标空间中图层的首选大小
/** Layout methods. **/
/* Returns the preferred frame size of the layer in the coordinate
* space of the superlayer. The default implementation calls the layout
* manager if one exists and it implements the -preferredSizeOfLayer:
* method, otherwise returns the size of the bounds rect mapped into
* the superlayer. */
返回父层坐标空间中图层的首选frame大小。 默认实现调用布局管理器layout manager
(如果存在的话),它实现-preferredSizeOfLayer:方法,否则返回映射到父层的边界矩形的大小。
- (CGSize)preferredFrameSize;
下面我们看一下和View绑定的layer的preferredFrameSize
,使用的是8plus的模拟器,代码如下:
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@"preferredFrameSize = %@", NSStringFromCGSize(self.view.layer.preferredFrameSize));
}
下面看输出结果
2018-01-23 12:22:02.879272+0800 JJLayer_demo3[49845:33682697] preferredFrameSize = {414, 736}
+ (nullable id<CAAction>)defaultActionForKey:(NSString *)event;
返回当前类默认的action。返回给定key对应的合适的action或者当与key关联的action对象不存在时返回nil。
/** Action methods. **/
/* An "action" is an object that responds to an "event" via the
* CAAction protocol (see below). Events are named using standard
* dot-separated key paths. Each layer defines a mapping from event key
* paths to action objects. Events are posted by looking up the action
* object associated with the key path and sending it the method
* defined by the CAAction protocol.
*
* When an action object is invoked it receives three parameters: the
* key path naming the event, the object on which the event happened
* (i.e. the layer), and optionally a dictionary of named arguments
* specific to each event.
*
* To provide implicit animations for layer properties, an event with
* the same name as each property is posted whenever the value of the
* property is modified. A suitable CAAnimation object is associated by
* default with each implicit event (CAAnimation implements the action
* protocol).
*
* The layer class also defines the following events that are not
* linked directly to properties:
*
* onOrderIn
* Invoked when the layer is made visible, i.e. either its
* superlayer becomes visible, or it's added as a sublayer of a
* visible layer
*
* onOrderOut
* Invoked when the layer becomes non-visible. */
/* Returns the default action object associated with the event named by
* the string 'event'. The default implementation returns a suitable
* animation object for events posted by animatable properties, nil
* otherwise. */
“action”是通过CAAction协议响应“event”的对象。 Events使用标准的点分离键路径命名。
每个图层都定义了从事件键路径到动作对象的映射。 通过查找与关键路径关联的操作对象来发布事件,
并把由CAAction协议定义的方法发送给它。
当一个action对象被调用时,它接收三个参数:命名事件的关键路径,事件发生位置的对象(即图层),
以及可选的特定于每个事件的命名参数的字典。
要为图层属性提供隐式动画,只要修改了属性的值,就会发布与每个属性同名的事件。 一个合适
的CAAnimation对象默认与每个隐式事件关联(CAAnimation实现action协议)。
图层类还定义以下不直接链接到属性的事件:
onOrderIn:在图层可见时调用,即其父图层变为可见,或者将其添加为可见图层的子图层。
onOrderOut:当图层变为不可见时调用。
返回与由字符串“event”命名的事件关联的默认action对象。 默认实现返回适合动画属性发布的
事件的动画对象,否则为nil。
+ (nullable id<CAAction>)defaultActionForKey:(NSString *)event;
还要注意以下几点:
想要提供默认的actions的类可以重写这个方法并返回这些actions。
我们知道Core Animation通常对CALayer的所有属性(可动画的属性)做动画,但是UIView把它关联的图层的这个特性关闭了。为了更好说明这一点,我们需要知道隐式动画是如何实现的。我们把改变属性时CALayer自动应用的动画称作行为,当CALayer的属性被修改时候,它会调
-actionForKey:
方法,传递属性的名称。图层首先检测它是否有委托,并且是否实现CALayerDelegate
协议指定的-actionForLayer:forKey
方法。如果有,直接调用并返回结果。如果没有委托,或者委托没有实现-actionForLayer:forKey
方法,图层接着检查包含属性名称对应行为映射的actions字典。如果actions字典没有包含对应的属性,那么图层接着在它的style字典接着搜索属性名。最后,如果在style里面也找不到对应的行为,那么图层将会直接调用定义了每个属性的标准行为的-defaultActionForKey:
方法。所以一轮完整的搜索结束之后,-actionForKey:
要么返回空(这种情况下将不会有动画发生),要么是CAAction协议对应的对象,最后CALayer拿这个结果去对先前和当前的值做动画。
参考文章
后记
本篇已结束,后面更精彩~~~