今天我们来学习一下一个在iOS常常被忽视的类 - CAReplicationLayer。我们要使用这个类来完成两个开起来很炫酷的加载效果。
老样子,先上具体的效果一看
怎么样,效果还不错吧。一个是看起来有渐变效果的圆形加载,另外一个则是模仿Apple Music的柱状图加载。
接下来,就让我们一起揭开实现的面纱吧!
CAReplicationLayer
CAReplicationLayer是CALayer的子类,它与传统的CALayer系列不同,它基本不直接承担诸多效果,而是更多的承担一种“容器”的职责。
怎么理解呢?大家可以把CAReplicationLayer看成一个工厂,你提供给他一个产品的模型,它就可以为了源源不断的复制出纺织品。回到iOS中来说就是,你提供一个CALayer给CAReplicationLayer,并告诉它你希望它复制几份,就打造出多个具有效果样式的Layer。不仅如此,动画效果也会被一同复制
因此,对于CAReplicationLayer,我们有几个特别需要关注的参数。
- instanceCount: 代表你希望将你提供它的Layer复制几份
- instanceDelay: 这个参数在编写动画的前提下特别有用,它表明对每一个复制(或者原生)出来的Layer,启动动画之间的时间差在多少。
- instanceTransform: 这个参数表示对于每一个Layer,它们之间的形变差距是多少。比如,每个Layer需要有相同的间隔。
渐变效果的圆形加载
了解完CAReplicationLayer的基本知识以后,我们首先来看看圆形加载效果怎么实现。
第一步,毫无疑问的,需要构建一个CAReplicationLayer。
let replicationLayer2 = CAReplicatorLayer()
第二部,需要一个样品,让我们的CAReplicationLayer复制生产
let circle = CAShapeLayer()
circle.path = UIBezierPath(ovalInRect: CGRect(x: 0, y: 0, width: 10, height: 10)).CGPath
circle.lineWidth = 1
circle.fillColor = UIColor.whiteColor().CGColor
circle.transform = CATransform3DMakeScale(0.1, 0.1, 0.1)
在这里,我们构建了一个白色小球,把初始大小设置为了0.1。
接下去,我们需要然CAReplicationLayer开始复制了,
replicationLayer2.instanceCount = 12
replicationLayer2.instanceTransform = CATransform3DMakeRotation(CGFloat(2 * M_PI/12.0), 0.0, 0.0, 1.0)
从上述代码我们可以看出,我们首先构建了12个复制体,然后将这12个小球通过instanceTransform绕Z轴均匀的分度在圆周上。
现在赶快run一下你的app,看看效果是不是正如我所说的!
现在万事具备,只欠动画了!
首先我们来定义如例子中的放缩动画
func scaleAnimation() -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: "transform.scale")
animation.duration = 1.5
animation.fromValue = 1.0
animation.toValue = 0.1
animation.repeatCount = Float.infinity
return animation
}
我们定义了一个针对scale属性、时常1.5s的动画,然后我们将这个动画添加到小球上。
circle.addAnimation(scaleAnimation(), forKey: "scale")
现在如果你跑一下代码的话,你会发现,所有的小球都同时启动了动画,和例子的效果不一致,怎么回事呢?
嘿嘿,还记得我们之前提及的属性instanceDelay吗?没错,我们需要借助它的力量。
replicationLayer2.instanceDelay = 1.5/12
现在再看看?哈哈,效果拔群!
Apple Music加载效果
下面的代码,很清晰易懂,我就不逐条解析啦,有问题欢迎大家在下方评论!
// 1. 创建容器ReplicationLayer
let replicationLayer = CAReplicatorLayer()
// 2. 创建柱状图
let bar = CALayer()
bar.frame = CGRect(x: 0, y: 0, width: 8, height: 40)
bar.position = CGPoint(x: 10, y: 75)
bar.backgroundColor = UIColor.purpleColor().CGColor
// 3. 复制生产3个,并添加水平间隔
replicationLayer.addSublayer(bar)
replicationLayer.instanceCount = 3
replicationLayer.instanceTransform = CATransform3DMakeTranslation(20, 0, 0)
// 4. 创建动画,构造时间差
func jumpAnimation(bar:CALayer) -> CABasicAnimation {
let animation = CABasicAnimation(keyPath: "position.y")
animation.toValue = bar.position.y - 35.0
animation.duration = 0.45
animation.autoreverses = true
animation.repeatCount = Float.infinity
return animation
}
bar.addAnimation(jumpAnimation(bar), forKey: "jump")
replicationLayer.instanceDelay = 0.3