前言
本篇主要写一些基于CALayer及其子类做的一些效果,结合CAAnimation做的好看常用的动画。代码在Github Example,废话不多说我们先看展示图
当前展示的效果
音乐播放器常用控件
系统加载中控件
毛玻璃蒙版效果
关键代码
音乐播放器常用控件
在音乐播放的app中我们经常看到这个控件,其实这个控件写起来很是简单,我们现在使用CAReplicatorLayer 来做这个效果 【为了方便演示,代码对控件进行放大演示】
func drawreplicatoreLayer() {
// 控件的长宽
let rtWidth:CGFloat = 150,rtheight:CGFloat = 120
let replicatoreLayer = CAReplicatorLayer()
replicatoreLayer.frame = CGRect(x: 0.0, y: 0.0, width: rtWidth, height: rtheight)
replicatoreLayer.position = view.center
view.layer.addSublayer(replicatoreLayer)
// 需要的重复的个数
let instanceCount:Int = 3
// 计算每一个的长宽
let itemLayerW:CGFloat = rtWidth/CGFloat(2*instanceCount+1)
let itemLayerH:CGFloat = rtheight/4.0*3.0
let itemLayer = CALayer()
itemLayer.frame = CGRect(x: itemLayerW, y: rtheight-itemLayerH, width: itemLayerW, height: itemLayerH)
itemLayer.cornerRadius = itemLayerH/20.0
itemLayer.backgroundColor = UIColor.red.cgColor
replicatoreLayer.addSublayer(itemLayer)
let move = CABasicAnimation(keyPath: "position.y")
move.toValue = itemLayer.position.y + itemLayerH-itemLayerH/5.0
move.duration = 0.5
move.autoreverses = true
move.repeatCount = Float.infinity
itemLayer.add(move, forKey: nil)
replicatoreLayer.instanceCount = 3
replicatoreLayer.instanceTransform = CATransform3DMakeTranslation(2*itemLayerW, 0.0, 0.0)
replicatoreLayer.instanceDelay = 0.33
replicatoreLayer.masksToBounds=true
}
系统加载中控件
首先我们创建一个父容器someView
let someView = UIView.init()
func createParentView(){
var w:CGFloat,h:CGFloat;
// 系统的控件是20 宽高 我们为了展示进行放大处理
w=self.view.frame.width/4.0
// w=20.0
h=w
someView.frame=CGRect.init(x: 0, y: 0, width: w, height: h)
someView.center=view.center
self.view.addSubview(someView)
}
创建活动指示器的Layer
func activityIndicatorLayerAnimation(){
// 1
let replicatorLayer = CAReplicatorLayer()
replicatorLayer.frame = someView.bounds
someView.layer.addSublayer(replicatorLayer)
// 2
let instanceCount = 12 //系统的控件是12个
replicatorLayer.instanceCount = instanceCount
replicatorLayer.instanceDelay = CFTimeInterval(1 / 30.0) //延迟时间
replicatorLayer.preservesDepth = false
// 3 颜色偏移
let AlphaOffset:Float = 0.1
replicatorLayer.instanceAlphaOffset = AlphaOffset
// 4 计算角度
let angle = Float(M_PI * 2.0)/Float(instanceCount)
replicatorLayer.instanceTransform = CATransform3DMakeRotation(CGFloat(angle), 0.0, 0.0, 1.0)
// 5
let instanceLayer = CALayer()
//第一个出现计算位置 我们这里计算的 正中心最下面的那一个item
let layerHeight: CGFloat = replicatorLayer.frame.width/3.0
let layerWidth: CGFloat = layerHeight/3.0
instanceLayer.frame = CGRect(x: (someView.bounds.width-layerWidth)/2.0, y: (someView.bounds.height-layerHeight), width: layerWidth, height: layerHeight)
instanceLayer.backgroundColor = UIColor.gray.cgColor
instanceLayer.cornerRadius = layerWidth/2.0 //圆角
replicatorLayer.addSublayer(instanceLayer)
// 6 添加动画
let fadeAnimation = CABasicAnimation(keyPath: "opacity")
fadeAnimation.fromValue = 0.6
fadeAnimation.toValue = AlphaOffset
fadeAnimation.duration = 1
fadeAnimation.repeatCount = Float(Int.max)
instanceLayer.add(fadeAnimation, forKey: "FadeAnimation")
}
以上就是CAReplicatorLayer 的简单使用,如果对CAReplicatorLayer有疑惑请翻阅developer CAReplicatorLayer
毛玻璃的蒙版效果
代码和讲解
func creatMaskAnimation() {
// 1 定义常量
let maskWidth:CGFloat = 180
let maskY:CGFloat = 100
// 2 创建路径
let maskPath = CGMutablePath.init()
let outsidePath = CGPath.init(rect: self.visualView.bounds, transform: nil)
let insidePath = CGPath.init(rect: CGRect.init(x: (self.view.bounds.width-maskWidth)/2.0, y: maskY, width: maskWidth, height: maskWidth), transform: nil)
maskPath.addPath(outsidePath)
maskPath.addPath(insidePath)
// 3 创建 CAShapeLayer
let maskLayer = CAShapeLayer.init()
maskLayer.fillRule="even-odd"
maskLayer.path = maskPath
// 经过测试 使用 visualView.Layer.mask 蒙版得以保留,但毛玻璃效果没有了 错误写法
// self.visualView.layer.mask=maskLayer
// 4 正确写法应该使用UIView.mask
let maskView = UIView.init(frame: self.view.bounds)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = maskLayer
self.visualView.mask = maskView
}