iOS CoreAnimation/CALayer 自定義屬性動畫demo及總結(jié)

CoreAnimation實現(xiàn)CALayer自定義屬性動畫有幾種方式,在這里做了個Demo都實現(xiàn)了√裰現(xiàn)在拿出來研究下伶椿,順便根據(jù)蘋果的官方文檔做了個總結(jié)。

先上Demo的效果圖:


自定義屬性動畫效果圖.gif

一、簡單的自定義屬性動畫
就是自定義的屬性脊另,使屬性像CALayer基類的屬性一樣导狡,可以通過設(shè)置屬性值來實現(xiàn)動畫效果。比如我demo中的白色圓環(huán)內(nèi)徑變化偎痛,設(shè)置圓環(huán)的內(nèi)徑增加10旱捧,然后反轉(zhuǎn),整個動畫效果無限循環(huán):

 let innerCirqueAnim = CABasicAnimation.init()
        innerCirqueAnim.keyPath = "circqueInnerRadius"
        innerCirqueAnim.duration = 1
        innerCirqueAnim.fromValue = animatorLayer!.circqueInnerRadius
        innerCirqueAnim.toValue = animatorLayer!.circqueInnerRadius + 10
        innerCirqueAnim.autoreverses = true
        innerCirqueAnim.repeatCount = Float.greatestFiniteMagnitude

        animatorLayer!.add(innerCirqueAnim, forKey: nil)

要實現(xiàn)這樣的效果需要的步驟如下:
1.創(chuàng)建一個基類繼承自CALayer

class ZoomAnimatingLayer: CALayer

2.創(chuàng)建與動畫效果有關(guān)的動態(tài)屬性( @NSManaged 等同于OC的Dynamic屬性)

  //    圓環(huán)內(nèi)部半徑
   @NSManaged public var circqueInnerRadius :CGFloat
    //    圓環(huán)外部半徑
   @NSManaged  public var circqueOuterRadius :CGFloat
     //    圓環(huán)中心
   @NSManaged  public var center :CGPoint
     //    填充顏色
   @NSManaged  public var fillColor :UIColor?
    
  1. 注冊需動態(tài)重繪的屬性
 // 注冊需動態(tài)重繪的屬性
     override class func needsDisplay(forKey key: String) -> Bool{
        print("needsDisplay(forKey key: String)")
        if key == "circqueInnerRadius" || key == "circqueOuterRadius" || key == "pausingRectEdge" {
            return true
        }
        return super.needsDisplay(forKey: key)
    }

4.重寫draw(in ctx: CGContext)方法,在方法中繪制自定義屬性依賴的圖形(關(guān)于CoreGraphics內(nèi)容本文不贅述,此處繪制的是一個圓環(huán)绊袋,里面有一個方形)

override func draw(in ctx: CGContext) {
        //繪圖相關(guān)內(nèi)容芽世,具體方法說明省略
        var finalCenter =  CGPoint.init(x: self.bounds.width/2, y: self.bounds.height/2)
        var finalColor = UIColor.white
        
        if !center.equalTo(CGPoint.zero) {
            finalCenter = center
        }
        
        if fillColor != nil {
            finalColor = fillColor!
        }
        
        let cirquePath = UIBezierPath.init()
        cirquePath.addArc(withCenter: finalCenter, radius: circqueInnerRadius, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)
        cirquePath.addArc(withCenter: finalCenter, radius: circqueOuterRadius, startAngle: 0, endAngle: CGFloat.pi*2, clockwise: true)
        ctx.addPath(cirquePath.cgPath)
        ctx.setFillColor(finalColor.cgColor)
        ctx.fillPath(using: CGPathFillRule.evenOdd)
        
        
        if showPausing {
            let roundRect = UIBezierPath.init(roundedRect: CGRect.init(x: finalCenter.x - pausingRectEdge/2, y: finalCenter.y - pausingRectEdge/2, width: pausingRectEdge, height: pausingRectEdge), cornerRadius: 5)
            ctx.addPath(roundRect.cgPath)
            ctx.setFillColor(finalColor.cgColor)
            ctx.fillPath(using: CGPathFillRule.winding)
        }
    }

完成上面的設(shè)置之后,執(zhí)行本節(jié)最開始的設(shè)置的 animatorLayer!.add(innerCirqueAnim, forKey: nil)遂跟,簡單的自定義屬性動畫就可以正常的運行了。

二、CALayer屬性關(guān)聯(lián)動畫(Animating properties )
屬性關(guān)聯(lián)動畫是本人自己的定義卢肃,具體的效果是,在設(shè)置CALayer及其子類的屬性的時候(可以是基類屬性星压,也可以是自定義的屬性)践剂,同時執(zhí)行一個動畫效果(整個效果可以和屬性沒有關(guān)系)。
例如娜膘,我可以在設(shè)置方形的邊長的時候逊脯,改變CALayer的透明度;當(dāng)然竣贪,通常情況下军洼,是設(shè)置針對本屬性的動畫效果,例如演怎,在我設(shè)置方形的邊長的時候匕争,設(shè)置一個改變邊長尺寸的動畫;

//設(shè)置層的方形的邊長增加10
  animatorLayer?.pausingRectEdge +=  10

實現(xiàn)這種效果有兩種方案:
方案1:重寫CALayer的action(forKey event: String) -> CAAction? 方法爷耀,設(shè)置修改屬性時甘桑,增加動畫效果:

         //設(shè)置屬性的屬性設(shè)置動畫:當(dāng)我們寫入該屬性的時候,會增加動畫效果歹叮;
    override func action(forKey event: String) -> CAAction? {
        print("action(forKey event: String)")
        if self.presentation() != nil {
//            self.presentation() 是在動畫過程中CALayer創(chuàng)建的針對動畫當(dāng)前顯示界面的顯示層跑杭;
            print(self.presentation()!)
            if event == "pausingRectEdge" {
                let rectEdge = CABasicAnimation.init(keyPath: event)
                rectEdge.fromValue = pausingRectEdge
                rectEdge.duration = 2
                
          //屬性設(shè)置動畫可以不是針對更改的屬性,可以是其他的屬性
//                let opacityAni = CABasicAnimation.init(keyPath: "opacity")
//                opacityAni.fromValue = 1
//                opacityAni.fromValue = 0.5
//                opacityAni.duration = 0.5
                
                return rectEdge
            }
        }
       
        return super.action(forKey: event)
    }

方案2:設(shè)置CALayer的屬性actions,actions是一個Dictionary咆耿,其成員必須符合[String : CAAction]德谅;

 //使用actions也能夠給屬性添加屬性設(shè)置動畫
        let outterCirqueAnim = CABasicAnimation.init()
        outterCirqueAnim.keyPath = "circqueOuterRadius"
        outterCirqueAnim.duration = 3
        outterCirqueAnim.fromValue = animatorLayer!.circqueOuterRadius
        animatorLayer!.actions = NSMutableDictionary.init(object: outterCirqueAnim, forKey:"circqueOuterRadius" as NSCopying) as? [String : CAAction]
        (animatorLayer?.actions!["circqueOuterRadius"] as! CABasicAnimation).fromValue = animatorLayer!.circqueOuterRadius
        animatorLayer!.circqueOuterRadius += 10

可以看出,兩種效果其實都是給屬性增加了一個CAAction萨螺。第2種方法有一個好處窄做,可以不重新創(chuàng)建新的CALayer子類愧驱,直接對CALayer基類屬性增加動畫。但是如果動畫要多次執(zhí)行椭盏,屬性值需要手工修正组砚;第1種方法需要重新創(chuàng)建自定義的CALayer,但是屬性值不需要手工修正庸汗,而且針對自定義屬性方便惫确;

三、官方文檔
根據(jù)官方文檔蚯舱,如果想要定義CALayer的屬性動畫需要以下幾步:
1.定義一個遵循了CAAction協(xié)議的對象(所有的CAAnimation改化、CATransition等動畫相關(guān)的都遵從該協(xié)議);
2.將CAAction添加到CALayer上枉昏。方式有幾種:
實現(xiàn)[actionForLayer:forKey:]代理方法陈肛;(本文使用的方式)
添加到actions字典中;(本文使用的方式)
添加到style字典中(本文使用的方式)
3.觸發(fā)CALayer的屬性兄裂,蘋果提出有四條觸發(fā)方式(設(shè)置屬性的方式):設(shè)置屬性時自動觸發(fā)(本文使用的方式句旱,例如設(shè)置圓環(huán)內(nèi)徑);CALayer實例對象剛開始可見時自動觸發(fā)[設(shè)置kCAOnOrderIn屬性]晰奖;CALayer開始不可見時自動觸發(fā)(設(shè)置kCAOnOrderOut屬性)谈撒;添加到了一個CATransition(添加CATransition方法);

具體Demo見我的GitHub

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末匾南,一起剝皮案震驚了整個濱河市啃匿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蛆楞,老刑警劉巖溯乒,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異豹爹,居然都是意外死亡裆悄,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門臂聋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來光稼,“玉大人,你說我怎么就攤上這事孩等“” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵瞎访,是天一觀的道長腻贰。 經(jīng)常有香客問我吁恍,道長扒秸,這世上最難降的妖魔是什么播演? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮伴奥,結(jié)果婚禮上写烤,老公的妹妹穿的比我還像新娘。我一直安慰自己拾徙,他們只是感情好洲炊,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尼啡,像睡著了一般暂衡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上崖瞭,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天狂巢,我揣著相機與錄音,去河邊找鬼书聚。 笑死唧领,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的雌续。 我是一名探鬼主播斩个,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼驯杜!你這毒婦竟也來了受啥?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤艇肴,失蹤者是張志新(化名)和其女友劉穎腔呜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體再悼,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡核畴,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了冲九。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谤草。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖莺奸,靈堂內(nèi)的尸體忽然破棺而出丑孩,到底是詐尸還是另有隱情,我是刑警寧澤灭贷,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布温学,位于F島的核電站,受9級特大地震影響甚疟,放射性物質(zhì)發(fā)生泄漏仗岖。R本人自食惡果不足惜逃延,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轧拄。 院中可真熱鬧揽祥,春花似錦、人聲如沸檩电。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽俐末。三九已至料按,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卓箫,已是汗流浹背站绪。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丽柿,地道東北人恢准。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像甫题,于是被迫代替她去往敵國和親馁筐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 在iOS中隨處都可以看到絢麗的動畫效果坠非,實現(xiàn)這些動畫的過程并不復(fù)雜敏沉,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,469評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果炎码,實現(xiàn)這些動畫的過程并不復(fù)雜盟迟,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,101評論 5 13
  • 書寫的很好潦闲,翻譯的也棒攒菠!感謝譯者,感謝感謝歉闰! iOS-Core-Animation-Advanced-Techni...
    錢噓噓閱讀 2,293評論 0 6
  • 如果想讓事情變得順利辖众,只有靠自己 -- 夏爾·紀(jì)堯姆 上一章介紹了隱式動畫的概念。隱式動畫是在iOS平臺創(chuàng)建動態(tài)用...
    雪_晟閱讀 564評論 0 1
  • 轉(zhuǎn)載:http://www.cnblogs.com/jingdizhiwa/p/5601240.html 1.ge...
    F麥子閱讀 1,536評論 0 1