CAReplicatorLayer
CAReplicatorLayer的目的是為了高效生成許多相似的圖層蝙泼。它會繪制一個或多個圖層的子圖層拳缠,并在每個復制體上應用不同的變換肥惭,復制的出來的layer和原來的子layer擁有相同的動效舅巷。它能夠重建包括自己在內(nèi)的n個copies套硼,這些copies是原layer中的所有sublayers垫毙,并且任何對原layer的sublayers設置的transform是可以積累的(accumulative)
CAReplicatorLayer屬性
- 設置實例顯示屬性(Setting Instance Display Properties)
/* The number of copies to create, including the source object.
* Default value is one (i.e. no extra copies). Animatable. */
// 創(chuàng)建副本的數(shù)量霹疫,包括原對象,默認有一個综芥,可動畫屬性
open var instanceCount: Int
/* The temporal delay between replicated copies. Defaults to zero.
* Animatable. */
// 顯示延時
open var instanceDelay: CFTimeInterval
/* The matrix applied to instance k-1 to produce instance k. The matrix
* is applied relative to the center of the replicator layer, i.e. the
* superlayer of each replicated sublayer. Defaults to the identity
* matrix. Animatable. */
// 對實例進行變換
open var instanceTransform: CATransform3D
- 修改實例幾何(Modifying Instance Layer Geometry)
/* Defines whether this layer flattens its sublayers into its plane or
* not (i.e. whether it's treated similarly to a transform layer or
* not). Defaults to NO. If YES, the standard restrictions apply (see
* CATransformLayer.h). */
//
open var preservesDepth: Bool
- 訪問實例顏色值(Accessing Instance Color Values)
/* The color to multiply the first object by (the source object). Defaults
* to opaque white. Animatable. */
open var instanceColor: CGColor?
/* The color components added to the color of instance k-1 to produce
* the modulation color of instance k. Defaults to the clear color (no
* change). Animatable. */
open var instanceRedOffset: Float
open var instanceGreenOffset: Float
open var instanceBlueOffset: Float
open var instanceAlphaOffset: Float
實戰(zhàn)
創(chuàng)建5個漸變的正方形
// 創(chuàng)建replicatorLayer
let replicatorLayer = CAReplicatorLayer()
replicatorLayer.frame = CGRect(x: 10, y: 100, width: 75, height: 75)
// 創(chuàng)建子layer
let redSquare = CALayer()
redSquare.backgroundColor = UIColor.white.cgColor
redSquare.frame = CGRect(x: 0, y: 0, width: 75, height: 75)
// 設置實例的個數(shù)
let instanceCount = 5
replicatorLayer.instanceCount = instanceCount
// 沿著x軸移動80丽蝎,80是正方形寬度75和間距5之和
replicatorLayer.instanceTransform = CATransform3DMakeTranslation(80, 0, 0)
// 設置顏色
let offsetStep = -1 / Float(instanceCount)
replicatorLayer.instanceBlueOffset = offsetStep
replicatorLayer.instanceGreenOffset = offsetStep
replicatorLayer.addSublayer(redSquare)
view.layer.addSublayer(replicatorLayer)
效果如下
屏幕快照 2018-11-19 下午5.35.25.png
反射效果
使用CAReplicatorLayer并應用一個負比例變換于一個復制圖層,你就可以創(chuàng)建指定視圖(或整個視圖層次)內(nèi)容的鏡像圖片膀藐,這樣就創(chuàng)建了一個實時的反射效果屠阻。
// 創(chuàng)建replicatorLayer
let replicatorLayer = CAReplicatorLayer()
replicatorLayer.frame = CGRect(x: 100, y: 100, width: 100, height: 100)
//注意:是包括自己在內(nèi)總共為2個對象
replicatorLayer.instanceCount = 2
// 創(chuàng)建transform
var transform = CATransform3DIdentity
let verticalOffset: CGFloat = replicatorLayer.bounds.height
// 沿y軸移動verticalOffset高度
transform = CATransform3DTranslate(transform, 0, verticalOffset + 2, 0)
// 沿著z軸旋轉180度
transform = CATransform3DRotate(transform, CGFloat.pi, 0, 0, 1)
// 使用transform
replicatorLayer.instanceTransform = transform
replicatorLayer.instanceAlphaOffset = -0.6
// 添加子layer
let subLayer = CALayer()
subLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
subLayer.contents = UIImage(named: "4")?.cgImage
replicatorLayer.addSublayer(subLayer)
效果如下
屏幕快照 2018-11-21 下午4.49.13.png
音量柱動畫
func musicAnimation() {
// 創(chuàng)建replicatorLayer
let replicatorLayer = CAReplicatorLayer()
let height: CGFloat = 230
replicatorLayer.frame = CGRect(x: 100, y: 100, width: height, height: height)
replicatorLayer.backgroundColor = UIColor.gray.cgColor
view.layer.addSublayer(replicatorLayer)
// 創(chuàng)建音量條
let volumeLayer = CALayer()
volumeLayer.backgroundColor = UIColor.cyan.cgColor
let volumeWidth: CGFloat = 30
volumeLayer.bounds = CGRect(x: 0, y: 0, width: volumeWidth, height: 100);
volumeLayer.anchorPoint = CGPoint(x: 0, y: 1)
volumeLayer.position = CGPoint(x: 0, y: height)
view.layer.addSublayer(volumeLayer)
// 對音量條添加動畫
let animation = CABasicAnimation(keyPath: "transform.scale.y")
animation.toValue = 0
animation.duration = 1.0
animation.repeatCount = Float.infinity
animation.autoreverses = true
volumeLayer.add(animation, forKey: nil)
replicatorLayer.addSublayer(volumeLayer)
// 設置音量條個數(shù)
replicatorLayer.instanceCount = 6
// 設置延時
replicatorLayer.instanceDelay = 0.35
// 設置透明度遞減
replicatorLayer.instanceAlphaOffset = -0.15
// 對每個音量震動條移動40
replicatorLayer.instanceTransform = CATransform3DMakeTranslation(volumeWidth + 10, 0, 0)
}
效果如下
2018-11-21 17-36-04.2018-11-21 17_36_18.gif
func dotLoading() {
let replicatorLayer = CAReplicatorLayer()
replicatorLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
replicatorLayer.position = view.center
view.layer.addSublayer(replicatorLayer)
// 添加小圓點
let dotLayer = CALayer()
dotLayer.bounds = CGRect(x: 0, y: 0, width: 10, height: 10)
dotLayer.position = CGPoint(x: 50, y: 20)
dotLayer.backgroundColor = UIColor(red: 0.1, green: 0.1, blue: 0.1, alpha: 0.6).cgColor
dotLayer.cornerRadius = 5;
dotLayer.masksToBounds = true
replicatorLayer.addSublayer(dotLayer)
// 添加縮放動畫
let animation = CABasicAnimation(keyPath: "transform.scale")
animation.duration = 1
animation.fromValue = 1
animation.toValue = 0.1
animation.repeatCount = Float.infinity
dotLayer.add(animation, forKey: nil)
// 設置個數(shù)
let count = 12
replicatorLayer.instanceCount = count
// 每次旋轉的角度等于 2π / 12
replicatorLayer.instanceTransform = CATransform3DMakeRotation((2 * CGFloat.pi) / CGFloat(count) , 0, 0, 1)
// 添加延遲
replicatorLayer.instanceDelay = CFTimeInterval(1.0 / CGFloat(count))
// 解決最開始旋轉銜接效果
dotLayer.transform = CATransform3DMakeScale(0.01, 0.01, 0.01);
}
效果如下
2018-11-21 17-53-55.2018-11-21 17_54_05.gif