Home ios - calayer
Post
Cancel

ios - calayer

class CALayer

1
An object that manages image-based content and allows you to perform animations on that content.
1
2
3
4
5
6
7
8
9
10
11
12
13
Layers are often used to provide the backing store for views but can also be used without a view to display content.

A layer’s main job is to manage the visual content that you provide but the layer itself has visual attributes that can be set, such as a background color, border, and shadow.

In addition to managing visual content, the layer also maintains information about the geometry of its content (such as its position, size, and transform) that is used to present that content onscreen.Modifying the properties of the layer is how you initiate animations on the layer’s content or geometry. 

A layer object encapsulates the duration and pacing of a layer and its animations by adopting the CAMediaTiming protocol, which defines the layer’s timing information.

If the layer object was created by a view, the view typically assigns itself as the layer’s delegate automatically, and you should not change that relationship.

For layers you create yourself, you can assign a delegate object and use that object to provide the contents of the layer dynamically and perform other tasks. 

A layer may also have a layout manager object (assigned to the layoutManager property) to manage the layout of subviews separately.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
/// An object that provides the contents of the layer. Animatable.
var contents: Any? { get set }

/* 
* The rectangle, in the unit coordinate space, that defines the portion of the layer’s contents that should be used. Animatable.

* Defaults to the unit rectangle (0.0, 0.0, 1.0, 1.0).
If pixels outside the unit rectangle are requested, the edge pixels of the contents image will be extended outwards.
*/
var contentsRect: CGRect { get set }

/*
* The rectangle that defines how the layer contents are scaled if the layer’s contents are resized. Animatable.

* You can use this property to subdivide the layer’s content into a 3x3 grid. The value in this property specifies the location and size of the center rectangle in that grid.

*  If the layer’s contentsGravity property is set to one of the resizing modes, resizing the layer causes scaling to occur differently in each rectangle of the grid. The center rectangle is stretched in both dimensions, the top-center and bottom-center rectangles are stretched only horizontally, the left-center and right-center rectangles are stretched only vertically, and the four corner rectangles are not stretched at all. Therefore, you can use this technique to implement stretchable backgrounds or images using a three-part or nine-part image.

* The value in this property is set to the unit rectangle (0.0,0.0) (1.0,1.0) by default, which causes the entire image to scale in both dimensions. If you specify a rectangle that extends outside the unit rectangle, the result is undefined. The rectangle you specify is applied only after the contentsRect property has been applied to the image.

*/
var contentsCenter: CGRect { get set }

/*
* A constant that specifies how the layer's contents are positioned or scaled within its bounds.
* The default value of this property is resize.

* The naming of contents gravity constants is based on the direction of the vertical axis.


*/
var contentsGravity: CALayerContentsGravity { get set }

/*
* Reloads the content of this layer.
* Do not call this method directly. The layer calls this method at appropriate times to update the layer’s content.

*  If the layer has a delegate object, this method attempts to call the delegate’s display(_:) method, which the delegate can use to update the layer’s contents.

* If the delegate does not implement the display(_:) method, this method creates a backing store and calls the layer’s draw(in:) method to fill that backing store with content. The new backing store replaces the previous contents of the layer.

* Subclasses can override this method and use it to set the layer’s contents property directly. You might do this if your custom layer subclass handles layer updates differently.
*/
func display()

/*
* Draws the layer’s content using the specified graphics context.
* The default implementation of this method does not do any drawing itself. If the layer’s delegate implements the draw(_:in:) method, that method is called to do the actual drawing.

* Subclasses can override this method and use it to draw the layer’s content. When drawing, all coordinates should be specified in points in the logical coordinate space.
*/
func draw(in ctx: CGContext)

/*
* Returns a copy of the presentation layer object that represents the state of the layer as it currently appears onscreen.

* The layer object returned by this method provides a close approximation of the layer that is currently being displayed onscreen. While an animation is in progress, you can retrieve this object and use it to get the current values for those animations.
*/
func presentation() -> Self?

/*
* Returns the model layer object associated with the receiver, if any.

* Calling this method on a layer in the presentation tree returns the corresponding layer object in the model tree. This method returns a value only when a transaction involving changes to the presentation layer is in progress. If no transaction is in progress, the results of calling this method are undefined.
*/
func model() -> Self

/*
* The opacity of the receiver. Animatable.
*/
var opacity: Float { get set }

/*
* A Boolean indicating whether sublayers are clipped to the layer’s bounds. Animatable.

* When the value of this property is true, Core Animation creates an implicit clipping mask that matches the bounds of the layer and includes any corner radius effects. If a value for the mask property is also specified, the two masks are multiplied to get the final mask value.
*/
var masksToBounds: Bool { get set }

/*
* An optional layer whose alpha channel is used to mask the layer’s content.

* The layer’s alpha channel determines how much of the layer’s content and background shows through. Fully or partially opaque pixels allow the underlying content to show through, but fully transparent pixels block that content.

* When configuring a mask, remember to set the size and position of the mask layer to ensure it is aligned properly with the layer it masks.

* The layer you assign to this property must not have a superlayer. If it does, the behavior is undefined.
*/
var mask: CALayer? { get set }

/*
* A Boolean indicating whether the layer displays its content when facing away from the viewer. Animatable

* When the value in this property is false, the layer hides its content when it faces away from the viewer.
*/
var isDoubleSided: Bool { get set }

/*
* The radius to use when drawing rounded corners for the layer’s background. Animatable.

* Setting the radius to a value greater than 0.0 causes the layer to begin drawing rounded corners on its background. By default, the corner radius does not apply to the image in the layer’s contents property; it applies only to the background color and border of the layer.

* However, setting the masksToBounds property to true causes the content to be clipped to the rounded corners.
*/
var cornerRadius: CGFloat { get set }

var maskedCorners: CACornerMask { get set }

/*
* The opacity of the layer’s shadow. Animatable.
*/
var shadowOpacity: Float { get set }

/*
* The blur radius (in points) used to render the layer’s shadow. Animatable.
* You specify the radius The default value of this property is 3.0.
*/
var shadowRadius: CGFloat { get set }

/*
* The offset (in points) of the layer’s shadow. Animatable.
* The default value of this property is (0.0, -3.0).
*/
var shadowOffset: CGSize { get set }

/*
* The color of the layer’s shadow. Animatable.
* The default value of this property is an opaque black color.
*/
var shadowColor: CGColor? { get set }

/*
* The shape of the layer’s shadow. Animatable.

* The default value of this property is nil, which causes the layer to use a standard shadow shape. If you specify a value for this property, the layer creates its shadow using the specified path instead of the layer’s composited alpha channel. The path you provide defines the outline of the shadow. It is filled using the non-zero winding rule and the current shadow color, opacity, and blur radius.

* Unlike most animatable properties, this property (as with all CGPathRef animatable properties) does not support implicit animation. However, the path object may be animated using any of the concrete subclasses of CAPropertyAnimation.

* Paths will interpolate as a linear blend of the "on-line" points; "off-line" points may be interpolated non-linearly (to preserve continuity of the curve's derivative). 

* If the two paths have a different number of control points or segments, the results are undefined.

* If the path extends outside the layer bounds it will not automatically be clipped to the layer, only if the normal layer masking rules cause that.

* Specifying an explicit path usually improves rendering performance.
*/
var shadowPath: CGPath? { get set }

/*
* An array of Core Image filters to apply to the contents of the layer and its sublayers. Animatable.

* The filters you add to this property affect the content of the layer, including its border, filled background and sublayers. The default value of this property is nil.

* Changing the inputs of the CIFilter object directly after it is attached to the layer causes undefined behavior.

* It is possible to modify filter parameters after attaching them to the layer but you must use the layer’s setValue(_:forKeyPath:) method to do so.

*  In addition, you must assign a name to the filter so that you can identify it in the array.

* This property is not supported on layers in iOS.
*/
var filters: [Any]? { get set }

/*
* A CoreImage filter used to composite the layer and the content behind it. Animatable.

* The default value of this property is nil, which causes the layer to use source-over compositing. Although you can use any Core Image filter as a layer's compositing filter, for best results, use those in the CICategoryCompositeOperation category.

* In macOS, it is possible to modify the filter’s parameters after attaching it to the layer but you must use the layer’s setValue(_:forKeyPath:) method to do so.

* This property is not supported on layers in iOS.
*/
var compositingFilter: Any? { get set }

/*
* An array of Core Image filters to apply to the content immediately behind the layer. Animatable.


* Background filters affect the content behind the layer that shows through into the layer itself. Typically this content belongs to the superlayer that acts as the parent of the layer.

* These filters do not affect the content of the layer itself, including the layer’s background color and border.

* Changing the inputs of the CIFilter object directly after it is attached to the layer causes undefined behavior. In macOS, it is possible to modify filter parameters after attaching them to the layer but you must use the layer’s setValue(_:forKeyPath:) method to do so. 
*/
var backgroundFilters: [Any]? { get set }

/*
* The filter used when reducing the size of the content.
* The possible values for this property are listed in Scaling Filters.
* The default value of this property is linear.
*/
var minificationFilter: CALayerContentsFilter { get set }

/*
* The bias factor used by the minification filter to determine the levels of detail.
* This value is used by the minificationFilter when it is set to trilinear.
* The default value of this property is 0.0.
*/
var minificationFilterBias: Float { get set }

/*
* The filter used when increasing the size of the content.
* The possible values for this property are listed in Scaling Filters.
* The default value of this property is linear.
*/
var magnificationFilter: CALayerContentsFilter { get set }

/*
* A Boolean value indicating whether the layer contains completely opaque content.

* The default value of this property is false. 

*  If your app draws completely opaque content that fills the layer’s bounds, setting this property to true lets the system optimize the rendering behavior for the layer. Specifically, when the layer creates the backing store for your drawing commands, Core Animation omits the alpha channel of that backing store. Doing so can improve the performance of compositing operations.

*  If you set the value of this property to true, you must fill the layer’s bounds with opaque content.

* Setting this property affects only the backing store managed by Core Animation.If you assign an image with an alpha channel to the layer’s contents property, that image retains its alpha channel regardless of the value of this property.

*/
var isOpaque: Bool { get set }

/*
* A bitmask defining how the edges of the receiver are rasterized.

* This property specifies which edges of the layer are antialiased and is a combination of the constants defined in CAEdgeAntialiasingMask.

* By default antialiasing is enabled for all edges.

* Typically, you would use this property to disable antialiasing for edges that abut edges of other layers, to eliminate the seams that would otherwise occur.
*/
var edgeAntialiasingMask: CAEdgeAntialiasingMask { get set }

/*
* Returns a Boolean indicating whether the layer content is implicitly flipped when rendered.
*/
func contentsAreFlipped() -> Bool

/*
* A Boolean that indicates whether the geometry of the layer and its sublayers is flipped vertically.
*/
var isGeometryFlipped: Bool { get set }

/*
* A Boolean indicating whether drawing commands are deferred and processed asynchronously in a background thread.

* When this property is set to true, the graphics context used to draw the layer’s contents queues drawing commands and executes them on a background thread rather than executing them synchronously. 

* Performing these commands asynchronously can improve performance in some apps. However, you should always measure the actual performance benefits before enabling this capability.
*/
var drawsAsynchronously: Bool { get set }

/*
* A Boolean that indicates whether the layer is rendered as a bitmap before compositing. Animatable

* When the value of this property is true, the layer is rendered as a bitmap in its local coordinate space and then composited to the destination with any other content.

* Shadow effects and any filters in the filters property are rasterized and included in the bitmap.

* However, the current opacity of the layer is not rasterized.

*  If the rasterized bitmap requires scaling during compositing, the filters in the minificationFilter and magnificationFilter properties are applied as needed.

* When the value of this property is false, the layer is composited directly into the destination whenever possible. The layer may still be rasterized prior to compositing if certain features of the compositing model (such as the inclusion of filters) require it.

* The default value of this property is false.
*/
var shouldRasterize: Bool { get set }

/*
* The scale at which to rasterize content, relative to the coordinate space of the layer. Animatable

* When the value in the shouldRasterize property is true, the layer uses this property to determine whether to scale the rasterized content (and by how much).
*/
var rasterizationScale: CGFloat { get set }

/*
* A hint for the desired storage format of the layer contents.

* The default value of this property is RGBA8Uint.

* UIView and layer-backed NSView objects may change the value to a format appropriate for the current device.
*/
var contentsFormat: CALayerContentsFormat { get set }

/*
* Renders the layer and its sublayers into the specified context.

* This method renders directly from the layer tree, ignoring any animations added to the render tree. Renders in the coordinate space of the layer
*/
func render(in ctx: CGContext)

/*
* The layer’s position in its superlayer’s coordinate space. Animatable.

* The value of this property is specified in points and is always specified relative to the value in the anchorPoint property. 

* For new standalone layers, the default position is set to (0.0, 0.0). Changing the frame property also updates the value in this property.
*/
var position: CGPoint { get set }

/*
* The layer’s position on the z axis. Animatable.
* The default value of this property is 0. Changing the value of this property changes the front-to-back ordering of layers onscreen.

* Higher values place this layer visually closer to the viewer than layers with lower values. This can affect the visibility of layers whose frame rectangles overlap.

* The value of this property is measured in points. The range of this property is single-precision, floating-point -greatestFiniteMagnitude to greatestFiniteMagnitude.
*/
var zPosition: CGFloat { get set }

/*
* The anchor point for the layer’s position along the z axis. Animatable.

* The default value of this property is 0.
*/
var anchorPointZ: CGFloat { get set }

/*
* Defines the anchor point of the layer's bounds rectangle. Animatable.

* You specify the value for this property using the unit coordinate space. 

* The default value of this property is (0.5, 0.5), which represents the center of the layer’s bounds rectangle.

* All geometric manipulations to the view occur about the specified point.

* For example, applying a rotation transform to a layer with the default anchor point causes the layer to rotate around its center. Changing the anchor point to a different location would cause the layer to rotate around that new point.
*/
var anchorPoint: CGPoint { get set }

/*
* The scale factor applied to the layer.

* This value defines the mapping between the logical coordinate space of the layer (measured in points) and the physical coordinate space (measured in pixels).

* Higher scale factors indicate that each point in the layer is represented by more than one pixel at render time.

* For example, if the scale factor is 2.0 and the layer’s bounds are 50 x 50 points, the size of the bitmap used to present the layer’s content is 100 x 100 pixels.

* The default value of this property is 1.0

* For layers attached to a view, the view changes the scale factor automatically to a value that is appropriate for the current screen.

*  For layers you create and manage yourself, you must set the value of this property yourself based on the resolution of the screen and the content you are providing.

* Core Animation uses the value you specify as a cue to determine how to render your content.
*/
var contentsScale: CGFloat { get set }

/*
* The transform applied to the layer’s contents. Animatable.

* This property is set to the identity transform by default. 
* Any transformations you apply to the layer occur relative to the layer’s anchor point.
*/
var transform: CATransform3D { get set }

/*
* Specifies the transform to apply to sublayers when rendering. Animatable.

* You typically use this property to add perspective and other viewing effects to embedded layers.

* You add perspective by setting the sublayer transform to the desired projection matrix.

* The default value of this property is the identity transform.
*/
var sublayerTransform: CATransform3D { get set }

/*
* Returns an affine version of the layer’s transform.
*/
func affineTransform() -> CGAffineTransform

/*
* Sets the layer’s transform to the specified affine transform.
*/
func setAffineTransform(_ m: CGAffineTransform)

/*
* A Boolean indicating whether the layer contents must be updated when its bounds rectangle changes.

* When this property is set to true, the layer automatically calls its setNeedsDisplay() method whenever its bounds property changes. 
*/
var needsDisplayOnBoundsChange: Bool { get set }

/*
* When the autoresizingMask property is used for resizing and the bounds of a layer change, that layer calls this method on each of its sublayers.

* Sublayers use this method to adjust their own frame rectangles to reflect the new superlayer bounds, which can be retrieved directly from the superlayer. 

* The old size of the superlayer is passed to this method so that the sublayer has that information for any calculations it must make.
*/
func resize(withOldSuperlayerSize size: CGSize)

/*
* When the autoresizingMask property is used for resizing and the bounds of this layer change, the layer calls this method.

* The default implementation calls the resize(withOldSuperlayerSize:) method of each sublayer to let it know its superlayer’s bounds changed. 

* You should not need to call or override this method directly.
*/
func resizeSublayers(withOldSize size: CGSize)

/*
* Returns the preferred size of the layer in the coordinate space of its superlayer.

* In macOS, the default implementation of this method calls the preferredSize(of:) method of its layout manager—that is, the object in its layoutManager property. If that object does not exist or does not implement that method, this method returns the size of the layer’s current bounds rectangle mapped into the coordinate space of its superlayer.
*/
func preferredFrameSize() -> CGSize

/*
* Add the specified animation object to the layer’s render tree.

- Parameter Key: A string that identifies the animation. Only one animation per unique key is added to the layer. The special key kCATransition is automatically used for transition animations. You may specify nil for this parameter.
*/
func add(_ anim: CAAnimation, 
  forKey key: String?)
/*
* Returns the animation object with the specified identifier.
- parameter key: 
A string that specifies the identifier of the animation. This string corresponds to the identifier string you passed to the add(_:forKey:) method.

* Modifying any properties of the returned object results in undefined behavior.
*/
func animation(forKey key: String) -> CAAnimation?

/*
* Remove all animations attached to the layer.
*/
func removeAllAnimations()

/*
* Returns an array of strings that identify the animations currently attached to the layer.
*/
func animationKeys() -> [String]?

/*
* Remove the animation object with the specified key.
*/
func removeAnimation(forKey key: String)

/*
* The object responsible for laying out the layer’s sublayers.
* If the layer’s delegate does not handle layout updates, the object assigned to this property is given a chance to update the layout of the layer’s sublayers.
* The default value of this property is nil.
*/
var layoutManager: CALayoutManager? { get set }
/*
* The layer’s delegate object.
* You can use a delegate object to provide the layer’s contents, handle the layout of any sublayers, and provide custom actions in response to layer-related changes. 

* In iOS, if the layer is associated with a UIView object, this property must be set to the view that owns the layer.
*/
weak var delegate: CALayerDelegate? { get set }
1
2
3
4
5
let buttonImage = UIImage(named: "button.png")
let layer = CALayer()
     
layer.contents = buttonImage?.cgImage
layer.contentsCenter = CGRect(x: 0.25, y: 0.25, width: 0.5, height: 0.5);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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

change the inputRadius parameter of the filter

1
2
3
4
5
6
7
8
let layer = CALayer()
         
if let filter = CIFilter(name:"CIGaussianBlur") {
    filter.name = "myFilter"
    layer.backgroundFilters = [filter]
    layer.setValue(1,
                   forKeyPath: "backgroundFilters.myFilter.inputRadius")
}

Applying a pointillize filter to a text layer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
view.layer = CALayer()
view.layerUsesCoreImageFilters = true
   
let textLayer = CATextLayer()
textLayer.string = "Core Animation"
textLayer.foregroundColor = NSColor.blue.cgColor
textLayer.backgroundColor = NSColor.lightGray.cgColor
textLayer.alignmentMode = kCAAlignmentCenter
textLayer.fontSize = 100
textLayer.frame = CGRect(x: 10, y: 10, width: 700, height: 140)
    
if let filter = CIFilter(name: "CIPointillize",
                         withInputParameters: ["inputRadius": 6]) {
    textLayer.filters = [filter]
}
   
view.layer?.addSublayer(textLayer)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
view.layer = CALayer()
view.layerUsesCoreImageFilters = true
     
let background = CATextLayer()
background.string = "background"
background.foregroundColor = NSColor.gray.cgColor
background.backgroundColor = NSColor.darkGray.cgColor
background.alignmentMode = kCAAlignmentCenter
background.fontSize = 96
background.frame = CGRect(x: 10, y: 10, width: 640, height: 160)
     
let foreground = CATextLayer()
foreground.string = "foreground"
foreground.foregroundColor = NSColor.lightGray.cgColor
foreground.backgroundColor = NSColor.darkGray.cgColor
foreground.alignmentMode = kCAAlignmentCenter
foreground.fontSize = 48
foreground.opacity = 0.5
foreground.frame = CGRect(x: 20, y: 20, width: 600, height: 60)
foreground.masksToBounds = false
     
if let compositingFilter = CIFilter(name: "CIAdditionCompositing") {
    foreground.compositingFilter = compositingFilter
}
     
view.layer?.addSublayer(background)
background.addSublayer(foreground)

background-filter

1
2
3
4
5
6
7
8
let layer = CALayer()
     
if let filter = CIFilter(name:"CIGaussianBlur") {
    filter.name = "myFilter"
    layer.backgroundFilters = [filter]
    layer.setValue(1,
                   forKeyPath: "backgroundFilters.myFilter.inputRadius")
}

magnification-filter

1
The circle on the left uses linear and the circle on the right uses nearest.

renderIn(ctx: )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let diameter: CGFloat = 100
let rect = CGRect(origin: CGPoint.zero,
                  size: CGSize(width: diameter, height: diameter))
    
let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = UIColor.white.cgColor
shapeLayer.lineWidth = 10
shapeLayer.path = CGPath(ellipseIn: rect,
                         transform: nil)
        
let renderer = UIGraphicsImageRenderer(size: rect.size)
     
let image = renderer.image {
    context in

    return shapeLayer.render(in: context.cgContext)
}

protocol CALayerDelegate

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
* Tells the delegate to implement the display process.
* The typical technique for updating is to set the layer's contents property.
- Example
class LayerDelegate: NSObject, CALayerDelegate {
    func display(_ layer: CALayer) {
        layer.contents = UIImage(named: "rabbit.png")?.cgImage
    }
}
*/
optional func display(_ layer: CALayer)

/*
* Tells the delegate to implement the display process using the layer's CGContext.

* The draw(_:in:) method is called when the layer is marked for its content to be reloaded, typically with the setNeedsDisplay() method.

* It is not called if the delegate implements the display(_:) method.

- Example
class LayerDelegate: NSObject, CALayerDelegate {
    func draw(_ layer: CALayer, in ctx: CGContext) {
        ctx.addEllipse(in: ctx.boundingBoxOfClipPath)
        ctx.strokePath()
    }
}
*/
optional func draw(_ layer: CALayer, 
                in ctx: CGContext)
/*
* Notifies the delegate of an imminent draw.
* The layerWillDraw(_:) method is called before draw(_:in:). 

* You can use this method to configure any layer state affecting contents prior to draw(_:in:) such as contentsFormat and isOpaque.
*/
optional func layerWillDraw(_ layer: CALayer)

/*
* Tells the delegate a layer's bounds have changed.

* The layoutSublayers(of:) method is called when a layer's bounds have changed and its sublayers may need rearranging, for example by changing its frame's size

* You can implement this method if you need precise control over the layout of your layer's sublayers.

- Example:
let delegate = LayerDelegate()
    
lazy var sublayer: CALayer = {
    let layer = CALayer()
    
    layer.addSublayer(CALayer())
    layer.sublayers?.first?.backgroundColor = UIColor.blue.cgColor
    
    layer.delegate = self.delegate
    
    return layer
}()
    
// sublayer.frame = CGRect(x: 0, y: 0, width: 510, height: 510)
    
class LayerDelegate: NSObject, CALayerDelegate {
    func layoutSublayers(of layer: CALayer) {
        layer.sublayers?.forEach {
            $0.frame = layer.bounds
        }
    }
}
*/
optional func layoutSublayers(of layer: CALayer)

/*
* Returns the default action of the action(forKey:) method.

* A layer's delegate that implements this method returns an action for a specified key and stops any further searches (i.e. actions for the same key in the layer's actions dictionary or specified by defaultAction(forKey:) are not returned).

- Example:

let delegate = LayerDelegate()
     
lazy var sublayer: CALayer = {
    let layer = CALayer()
    layer.delegate = self.delegate
    
    return layer
}()
     
func moveSublayer() {
    guard let action = sublayer.action(forKey: "moveRight") else {
        return
    }
    
    action.run(forKey: "transform", object: sublayer, arguments: nil)
}
     
class LayerDelegate: NSObject, CALayerDelegate {
    func action(for layer: CALayer, forKey event: String) -> CAAction? {
        
        guard event == "moveRight" else {
            return nil
        }
        
        let animation = CABasicAnimation()
        animation.valueFunction = CAValueFunction(name: kCAValueFunctionTranslateX)
        animation.fromValue = 1
        animation.toValue = 300
        animation.duration = 2
        
        return animation
    }
}
*/
optional func action(for layer: CALayer, 
              forKey event: String) -> CAAction?
This post is licensed under CC BY 4.0 by the author.