iOS動畫系列之九:實現點讚的動畫及播放起伏指示器(OC+Swift)

非典型技術宅發表於2017-11-19


iOS動畫系列,共十篇。現在寫到第九篇啦。最近寫程式碼有點疲憊,一點都不想動,突然敲起程式碼,那個手生呀~所以說,碼農就是熟練工種還是有一定道理的。

今天主要通過實現一個音樂播放狀態的展示條,還有一個點讚的動畫效果,來看看
CAReplicatorLayer、CAEmitterLayer和CAGradientLayer這三個專用層。

還是老慣例啦,先看看實現後的效果是啥樣子。

播放指示器.gif
播放指示器.gif

點贊動畫
點贊動畫

漸變色.gif
漸變色.gif

1.CAReplicatorLayer

CAReplicatorLayer的目的是為了高效生成許多相似的圖層。它會繪製一個或多個圖層的子圖層,並在每個複製體上應用不同的變換。什麼意思?看到例子中間的那麼多條條在上下起伏了嘛?其實我並沒有寫那麼多條條,只寫了一個。把這一個寫好的加入到了CAReplicatorLayer複製層中,然後就根據設定的引數自動的生成了剩下的條狀物。

播放指示器.gif
播放指示器.gif

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屬性介紹

為了能夠看到各個屬性之間的含義,所以又來了第二個複製層。第二個複製層修改了複製的錨點、複製的個數、複製的偏移量。
來,我們一起對照看看兩個複製層上面有什麼區別。

指示器2.gif
指示器2.gif

我們看看官方對於這個層有哪些屬性:


    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的真正好處在於繪製使用了硬體加速。
實現效果如下:

漸變色.gif
漸變色.gif

    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動畫系列之九:實現點讚的動畫及播放起伏指示器
第十篇:實戰系列:繪製過山車場景

相關文章