iOS動畫系列,共十篇。現在寫到第九篇啦。最近寫程式碼有點疲憊,一點都不想動,突然敲起程式碼,那個手生呀~所以說,碼農就是熟練工種還是有一定道理的。
今天主要通過實現一個音樂播放狀態的展示條,還有一個點讚的動畫效果,來看看
CAReplicatorLayer、CAEmitterLayer和CAGradientLayer這三個專用層。
還是老慣例啦,先看看實現後的效果是啥樣子。
1.CAReplicatorLayer
CAReplicatorLayer
的目的是為了高效生成許多相似的圖層。它會繪製一個或多個圖層的子圖層,並在每個複製體上應用不同的變換。什麼意思?看到例子中間的那麼多條條在上下起伏了嘛?其實我並沒有寫那麼多條條,只寫了一個。把這一個寫好的加入到了CAReplicatorLayer
複製層中,然後就根據設定的引數自動的生成了剩下的條狀物。
1.1 第一步:先寫好一個層,剩下的都複製這個
let layer = CALayer.init()
layer.frame = CGRect.init(x: 0, y: 0, width: 10, height: 80)
layer.backgroundColor = UIColor.white.cgColor
layer.anchorPoint = CGPoint.init(x: 0.5, y: 0.5)
layer.add(self.scaleYAnimation(), forKey: "scaleAnimation")
fileprivate func scaleYAnimation() -> CABasicAnimation{
let anim = CABasicAnimation.init(keyPath: "transform.scale.y")
anim.toValue = 0.1
anim.duration = 0.4
anim.autoreverses = true
anim.repeatCount = MAXFLOAT
return anim
}複製程式碼
這些都沒啥問題把?就是最基本的建立一個CALayer,設定了frame,設定了錨點,設定了背景顏色,加入了上下移動的動畫。
等等,為什麼這裡背景顏色是白色吶?白色不是就看不見了嘛?彆著急,第二步裡面答案就揭曉啦。
1.2 第二步:使用CAReplicatorLayer進行復制
// 設定複製層裡面包含子層的個數
replicatorLayer.instanceCount = 6
// 設定子層相對於前一個層的偏移量
replicatorLayer.instanceTransform = CATransform3DMakeTranslation(45, 0, 0)
// 設定子層相對於前一個層的延遲時間
replicatorLayer.instanceDelay = 0.2
// 設定層的顏色,(前提是要設定層的背景顏色,如果沒有設定背景顏色,預設是透明的,再設定這個屬性不會有效果。
replicatorLayer.instanceColor = UIColor.green.cgColor
// 顏色的漸變,相對於前一個層的漸變(取值-1~+1).RGB有三種顏色,所以這裡也是綠紅藍三種。
replicatorLayer.instanceGreenOffset = -0.2
replicatorLayer.instanceRedOffset = -0.2
replicatorLayer.instanceBlueOffset = -0.2
// 需要把子層加入到複製層中,複製層按照前面設定的引數自動複製
replicatorLayer.addSublayer(layer)
// 將複製層加入view的層裡面進行顯示
view.layer.addSublayer(replicatorLayer)複製程式碼
看到了木有?前面那個基準層的背景顏色為啥是白色吶?最終生效的其實還是replicatorLayer.instanceColor = UIColor.green.cgColor
。
這樣就齊活啦~就完事兒了,就這麼簡單。
1.3 CAReplicatorLayer屬性介紹
為了能夠看到各個屬性之間的含義,所以又來了第二個複製層。第二個複製層修改了複製的錨點、複製的個數、複製的偏移量。
來,我們一起對照看看兩個複製層上面有什麼區別。
我們看看官方對於這個層有哪些屬性:
open var instanceCount: Int
open var preservesDepth: Bool
open var instanceDelay: CFTimeInterval
open var instanceTransform: CATransform3D
open var instanceColor: CGColor?
open var instanceRedOffset: Float
open var instanceGreenOffset: Float
open var instanceBlueOffset: Float
open var instanceAlphaOffset: Float複製程式碼
一共有九個屬性對吧?一起來看看都啥意思。
instanceCount:拷貝圖層的次數,包括其所有的子圖層,預設值是1,也就是沒有任何子圖層被複制。
preservesDepth:如果設定為YES,圖層將保持於CATransformLayer類似的性質和相同的限制
- instanceDelay:設定子層相對於前一個層的延遲時間
- instanceTransform: 設定子層相對於前一個層的偏移量
- instanceColor:設定層的顏色,(前提是要設定層的背景顏色,如果沒有設定背景顏色,預設是透明的,再設定這個屬性不會有效果。
- instanceRedOffset、instanceGreenOffset、instanceBlueOffset:顏色的漸變,相對於前一個層的漸變(取值-1~+1).RGB有三種顏色,所以這裡也是綠紅藍三種。
- instanceAlphaOffset:相對於前一個層透明圖的漸變。
2. CAEmitterLayer
CAEmitterLayer是一個高效能的粒子引擎,被用來建立實時例子動畫如:煙霧,火,雨等等這些效果。CAEmitterLayer看上去像是許多CAEmitterCell的容器,這些CAEmitierCell定義了一個例子效果。
通俗點說,例如雨是由很多小雨點組成的。每個小雨點就是
CAEmitterCell,CAEmitterLayer用來控制這些小雨點。我們不用太關心cell的建立和銷燬,只要設定好引數,系統會幫助我們完成這些工作。
那我們就通過一個點讚的動畫來看看到底怎麼用。實現的效果如下:
2.1 第一步:建立一個大拇指的button
建立一個button,設定選中狀態、普通狀態的圖片。寫好觸發事件。這個沒什麼好解釋的,就是點一下把狀態改一下。
//點選按鈕事件
@IBAction func priaseBtnClick(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
}複製程式碼
2.2 第二步:自定義button
為了能夠讓button具有動畫效果,需要自定義這個button。因此我們需要重寫button的初始化方法、button狀態改變的方法。
swift裡面重寫方法的格式和OC不太一樣,需要注意一下。
//重寫狀態改變的方法
override var isSelected: Bool{
didSet{
// 執行動畫
explosionAni()
}
}
//重寫button初始化方法
override init(frame: CGRect) {
explosionLayer = CAEmitterLayer.init()
super.init(frame: frame)
setupExplosion()
}
required init?(coder aDecoder: NSCoder) {
explosionLayer = CAEmitterLayer.init()
super.init(coder: aDecoder)
setupExplosion()
// fatalError("init(coder:) has not been implemented")
}複製程式碼
2.3 建立點贊周圍的那些小點點的單個元素,通過CAEmitterCell實現
基本上CAEmitterCell該用的屬性都用到了,剩下的我們們會在下面繼續補充。
let explosionCell = CAEmitterCell.init()
explosionCell.name = "explosion"
// 設定粒子顏色alpha能改變的範圍
explosionCell.alphaRange = 0.10
// 粒子alpha的改變速度
explosionCell.alphaSpeed = -1.0
// 粒子的生命週期
explosionCell.lifetime = 0.7
// 粒子生命週期的範圍
explosionCell.lifetimeRange = 0.3
// 粒子發射的初始速度
explosionCell.birthRate = 2500
// 粒子的速度
explosionCell.velocity = 40.00
// 粒子速度範圍
explosionCell.velocityRange = 10.00
// 粒子的縮放比例
explosionCell.scale = 0.03
// 縮放比例範圍
explosionCell.scaleRange = 0.02
// 粒子要展現的圖片
explosionCell.contents = UIImage(named: "sparkle")?.cgImage複製程式碼
2.4 設定CAEmitterLayer,讓它控制cell
explosionLayer.name = "explosionLayer"
// 發射源的形狀
explosionLayer.emitterShape = kCAEmitterLayerCircle
// 發射模式
explosionLayer.emitterMode = kCAEmitterLayerOutline
// 發射源大小
explosionLayer.emitterSize = CGSize.init(width: 10, height: 0)
// 發射源包含的粒子
explosionLayer.emitterCells = [explosionCell]
// 渲染模式
explosionLayer.renderMode = kCAEmitterLayerOldestFirst
explosionLayer.masksToBounds = false
explosionLayer.birthRate = 0
// 發射位置
explosionLayer.position = CGPoint.init(x: frame.size.width/2, y: frame.size.height/2)
explosionLayer.zPosition = -1
layer.addSublayer(explosionLayer)複製程式碼
2.5 設定動畫的引數
這裡的動畫基本上就只是CAKeyframeAnimation,很簡單。如果有不太清楚的,可以看看前面的這個 第七篇:CAKeyFrame Animation和CAAnimation Group。。
2.6 CAEmitterLayer的屬性
基本上該用的屬性這個粒子裡面都用到了,唯一以後需要查手冊的就是下面這些列舉。
// emitterShape values. 發射器形狀
@available(iOS 5.0, *)
public let kCAEmitterLayerPoint: String //點
@available(iOS 5.0, *)
public let kCAEmitterLayerLine: String //線
@available(iOS 5.0, *)
public let kCAEmitterLayerRectangle: String //矩形
@available(iOS 5.0, *)
public let kCAEmitterLayerCuboid: String //長方形
@available(iOS 5.0, *)
public let kCAEmitterLayerCircle: String //圓形
@available(iOS 5.0, *)
public let kCAEmitterLayerSphere: String //球形
// emitterMode values. 發射模式
@available(iOS 5.0, *)
public let kCAEmitterLayerPoints: String //點狀
@available(iOS 5.0, *)
public let kCAEmitterLayerOutline: String //輪廓
@available(iOS 5.0, *)
public let kCAEmitterLayerSurface: String //表面
@available(iOS 5.0, *)
public let kCAEmitterLayerVolume: String //大量
// renderMode values. 渲染模式
@available(iOS 5.0, *)
public let kCAEmitterLayerUnordered: String //亂序
@available(iOS 5.0, *)
public let kCAEmitterLayerOldestFirst: String //最老的最先出來
@available(iOS 5.0, *)
public let kCAEmitterLayerOldestLast: String //最老的最後出來
@available(iOS 5.0, *)
public let kCAEmitterLayerBackToFront: String //前後顛倒
@available(iOS 5.0, *)
public let kCAEmitterLayerAdditive: String //附加複製程式碼
這些不用記,不用背。用的時候查一下就可以了。
3. CAGradientLayer
CAGradientLayer是用來生成兩種或更多顏色平滑漸變的。用Core Graphics複製一個CAGradientLayer並將內容繪製到一個普通圖層的寄宿圖也是有可能的,但是CAGradientLayer的真正好處在於繪製使用了硬體加速。
實現效果如下:
func createGradientLayer(){
gradientlayer = CAGradientLayer.init()
gradientlayer.frame = view.bounds
// 設定顏色組。這裡設定了黑色、藍色、橙色、紅色、綠色五種顏色
gradientlayer.colors = [UIColor.black.cgColor,UIColor.blue.cgColor,UIColor.orange.cgColor,UIColor.red.cgColor,UIColor.green.cgColor]
// 根據起點指向終點的方向來漸變顏色,範圍是0~1
gradientlayer.startPoint = CGPoint(x: 0.0, y: 0.0)
gradientlayer.endPoint = CGPoint(x: 1.0, y: 1.0)
// 設定顏色分割線,範圍是0~1
gradientlayer.locations = [0.1,0.5,0.7,0.75,0.95]
view.layer.addSublayer(gradientlayer)
}複製程式碼
swift版和OC版的原始碼可以在這裡下載。git.oschina.net/atypical/mu…
-----------------------華麗分割線,iOS動畫系列全集連結-------------------------------------------------
第一篇:iOS動畫系列之一:通過實戰學習CALayer和透視的原理。做一個帶時分秒指標的時鐘動畫(上)
第二篇:iOS動畫系列之二:通過實戰學習CALayer和透視的原理。做一個帶時分秒指標的時鐘動畫。包含了OC和Swift兩種原始碼(下)
第三篇:iOS動畫系列之三:Core Animation。介紹了Core Animation的常用屬性和方法。
第四篇:CABasic Animation。iOS動畫系列之四:基礎動畫之平移篇
第五篇:CABasic Animation。iOS動畫系列之五:基礎動畫之縮放篇&旋轉篇
第六篇:iOS動畫系列之六:利用CABasic Animation完成帶動畫特效的登入介面
第七篇:iOS動畫系列之七:實現類似Twitter的啟動動畫
第八篇:iOS動畫系列之八:使用CAShapeLayer繪畫動態流量圖
第九篇:iOS動畫系列之九:實現點讚的動畫及播放起伏指示器
第十篇:實戰系列:繪製雲霄飛車場景