使用CAReplicatorLayer創(chuàng)建動畫

在網(wǎng)上看到了這篇文章币砂,寫得很好移国,于是便把它翻譯出來,這是我第一次翻譯道伟,翻得不好請輕噴,畢竟6級都沒過的孩子使碾,苦逼啊蜜徽。
原文鏈接:http://www.ios-animations-by-emails.com/posts/2015-march#tutorial

這是2015年3月的iOS動畫,這個教程將引導(dǎo)您通過使用CAReplicatorLayer創(chuàng)建很酷的動畫票摇。你可能從來沒有聽說過CAReplicatorLayer拘鞋,那是一個很酷難以理解但強大的CoreAnimation類。
我想借此機會感謝大家誰不停地傳播這個詞iOS Animations by Emails 矢门,并幫助這最后的一個月中我們的動畫界近1,000強勁增長盆色。非常感謝所有誰Tweet宣傳我的書的iOS動畫教程所 -你們是最棒的!
我希望祟剔,當你通過這個月的教程中看到你會很高興隔躲,我把我的甜蜜的時間來準備這些:]享受!

                                    ——- 馬林托多羅夫

教程:創(chuàng)建動畫與CAReplicatorLayer

-本教程是專為Xcode的6.1.1或兼容的版本物延。

當我正在iOS的動畫教程由 CAReplicatorLayer在我的頭腦和我的主題列表了宣旱。然而,當我們的計劃書叛薯,我們意識到并非所有的圖層將使其在和CAReplicatorLayer被留下(他一生的故事浑吟!)。
然而耗溜,這一個月的通訊是所有關(guān)于CAReplicatorLayer组力,我敢肯定,這將讓我的技術(shù)編輯這本書富特頓很高興抖拴。
在本教程中我將指導(dǎo)您完成創(chuàng)建3個不同的電源動畫使用CAReplicatorLayer燎字。
我們將從模仿內(nèi)置在iOS的音樂中得音量振動條(原文“volume bars”)來開始這個教程。

第二步你將繼續(xù)創(chuàng)建一個自定義的活動指示燈,最后您將創(chuàng)建一個動畫來呈現(xiàn)raywenderlich.com在屏幕上的標志在一個不尋常的方式:

1.基本復(fù)制動畫

CAReplicatorLayer是一個容器層-你添加內(nèi)容到其中讓復(fù)制圖層復(fù)制其中內(nèi)容轩触。如果你把一個單一的形狀-在復(fù)制層將顯示在屏幕上幾種形狀寞酿。
很酷的是你可以預(yù)先設(shè)定復(fù)制多少幾何圖形并且設(shè)定副本之間的距離,透明度或顏色都可以發(fā)生變化脱柱。因此您可以創(chuàng)建很酷的動畫效果伐弹。
在本教程的第一部分,你會從iOS的音樂應(yīng)用程序山寨動畫:


這個動畫設(shè)有一個上下移動的紅色矩形榨为。副本之間存在位置和時間偏移惨好。讓我們開始吧!

創(chuàng)建一個新的Xcode項目随闺,并選擇單一視圖模板(Single View template)日川。保存項目后打開ViewController.swift
viewDidLoad中()添加以下代碼 :

func animation1() {

}

并添加了一個空方法在ViewController

func animation1() { 

}

讓我們開始創(chuàng)建復(fù)制層矩乐,添加方法 animation1()

let r = CAReplicatorLayer() 
r.bounds = CGRect(x: 0.0, y: 0.0, width: 60.0, height: 60.0) 
r.position = view.center 
r.backgroundColor = UIColor.lightGrayColor().CGColor 
view.layer.addSublayer(r)

這段代碼創(chuàng)建了一個CAReplicatorLayer的實例并且設(shè)置其邊界和位置龄句。為了確定它在哪兒,我們得給它一個淺灰色的背景顏色散罕,然后將其添加到視圖控制器的視圖層分歇。
現(xiàn)在運行應(yīng)用程序,你會看到屏幕出現(xiàn)一條淺灰色的方形:


現(xiàn)在欧漱,讓我們創(chuàng)建的第一個矩形(也可以說成是原始的矩形)职抡,在animation1()中添加代碼

let bar = CALayer() 
bar.bounds = CGRect(x: 0.0, y: 0.0, width: 8.0, height: 40.0) 
bar.position = CGPoint(x: 10.0, y: 75.0) 
bar.cornerRadius = 2.0 
bar.backgroundColor = UIColor.redColor().CGColor 
r.addSublayer(bar)

這段代碼創(chuàng)建一個紅色的圓角矩形,并將其定位在復(fù)制層的左側(cè)误甚。運行應(yīng)用程序在看效果:

紅色的圓角矩形出現(xiàn)在復(fù)制層外面缚甩,因為我們會讓他上下移動。該動畫的起始位置是復(fù)制界限之下 - 這就是為什么矩形似乎有點“偏”窑邦。
說到動畫擅威,接下來添加動畫代碼如下:

let move = CABasicAnimation(keyPath: "position.y") 
move.toValue = bar.position.y - 35.0 
move.duration = 0.5 
move.autoreverses = true 
move.repeatCount = Float.infinity 
bar.addAnimation(move, forKey: nil)

這將使紅條反復(fù)的上下移動,這是一個很好的開始冈钦,雖然它看起來并不令人印象深刻裕寨,現(xiàn)在你是在事實上幾乎已經(jīng)準備好與你最終的動畫!
接著來復(fù)制派继!添加以下代碼:

r.instanceCount = 3

這告訴你想在屏幕上現(xiàn)實內(nèi)容的3份拷貝(包括原來的)宾袜。如果你運行應(yīng)用程序,當讓驾窟,現(xiàn)在你將不會看到任何變化庆猫,因為所有的3份拷貝都出現(xiàn)在相同的位置,并在同一時間進行同一動畫绅络。為了到達效果我們給每個拷貝加上向右的偏移:

r.instanceTransform = CATransform3DMakeTranslation(20.0月培,0.0嘁字,0.0)

這段代碼告訴復(fù)制圖層執(zhí)行怎樣的變換到內(nèi)容。您可以設(shè)置instanceTransform的值為偏移20每一個杉畜,當您運行的應(yīng)用程序纪蜒,你應(yīng)該可以看到3紅柱彼此相鄰:

原來的紅色條和兩個克隆都動畫都在上下往復(fù)運動,酷此叠!最后一步纯续,以實現(xiàn)期望的動畫效果是給每個條一比特延遲,使它們不會在一致地移動灭袁。加入一個代碼最后一行:

r.instanceDelay = 0.33

instanceDelay是時間偏移復(fù)制圖層渲染猬错。動畫將分別會有0.33s延遲0.66s的延遲。
運行應(yīng)用程序并檢查結(jié)果 - 你應(yīng)該看到矩形跳來跳去茸歧,就像在原來的動畫倦炒。
最后,你需要做兩個快速的變化:

  • 讓紅色矩形只顯示在灰色矩形里面的內(nèi)容;
r.masksToBounds = true

  • 刪除backgroundColor

如果你想不同的動畫就去改變instanceCount软瞎,instanceTransforminstanceDelay逢唤。很酷,不是嗎涤浇?

2.活動指示燈

記者我們來做更復(fù)雜的復(fù)制動畫智玻!切換到到viewDidLoad方法中()
替換animation1():

animation2()

正如你想得一樣,下一個步驟就是添加一個空的方法:

func animation2(){ 

}

在這部分教程你要創(chuàng)建活動指示器芙代。為了好玩,我們將創(chuàng)建一個比內(nèi)置的iOS的活動指示器更精細的動畫盖彭。
首先添加一個復(fù)制圖層到視圖控制器纹烹,加入到animation2()

let R = CAReplicatorLayer()
r.bounds = CGRect(0.0,0.0,200.0,200.0)
r.cornerRadius = 10.0 
r.backgroundColor = UIColor(white:0.0,alpha:0.75).CGColor 
r.position = view.center 
view.layer.addSublayer(r)

然后以完全相同的方式添加一個空的復(fù)制層灰色背景召边。這會讓我們背景顏色來模擬一個HUD的活動铺呵。
接下來添加繪制一個白色矩形屏幕上的一個簡單的一層:

let dot = CALayer()
dot.bounds = CGRect(0.0,0.0,14.0,14.0)
dot.position = CGPoint(100.0,40.0)
dot.backgroundColor = UIColor(whilte:0.8,alpha:1.0).CGColor 
dot.borderColor =UIColor(white:1.0,alapha:1.0).CGColor 
dot.borderWidth = 1.0 
dot.cornerRadius = 2.0 
r.addSublayer(dot)

創(chuàng)建一個14×14的矩形,并給它一個2磅圓角半徑隧熙。在最后你添加dot層的復(fù)制片挂。
現(xiàn)在運行應(yīng)用程序,看看一切看起來就像至今:

現(xiàn)在復(fù)制15個點來組成一個圈贞盯,每次旋轉(zhuǎn)的角度等于2π/ 15:

let nrDots:INT = 15 

r.instanceCount = nrDots 
let angle= CGFloat(2 * M_PI)/ CGFloat(nrDots)
r.instanceTransform = CATransform3DMakeRotation(agnle : 0.0,0.0,1.0)

設(shè)置instanceCount為15音念,設(shè)置了旋轉(zhuǎn)變換使用2π/ 15的角度。
再次運行應(yīng)用程序躏敢,你將會看到這樣一個漂亮的畫面:

你可以通過改變nrDots 到10闷愤,25或者其他值來輕松的達到你想要的效果,復(fù)制器乖乖計算幾何和渲染點的克录唷:

現(xiàn)在讥脐,讓我們做一段1.5秒的動畫遭居。在到原來的點上做縮放變化:

let duration :CFTimeInterval = 1.5 

let shrink = CABasicAnimation(keyPath:"transform.scale")
shrink.fromValue = 1.0 
shrink.toValue = 0.1 
shrink.duration = duration
shrink.repeatCount = Float.infinity 
dot.addAnimation(shrink,forKey:nil)

這樣就做出了一個催眠動畫,所有的點一遍遍的變大變小旬渠。(千萬不要盯著太久俱萍,以免被催眠哦)
當你希望記住的方法,使動畫動起來的秘訣就是給出一點延遲到每一個副本告丢,
就像這樣

r.instanceDelay =duration/Double(nrDots)

這將讓您的動畫旋轉(zhuǎn)很好枪蘑。動畫的第一個旋轉(zhuǎn)有一個有點怪,但是在第一次旋轉(zhuǎn)之后芋齿,所有的點就都是可見的
為了解決這個問題腥寇,我們可以第一次的點進行縮放,在動畫開始之前,加上這個代碼最后一行到animation2() :

dot.transform = CATransform3DMakeScale(0.01,0.01觅捆,0.01)赦役。

這將使動畫變得更加流暢。

做到這栅炒,是否感覺做動畫比想象中要簡單的多掂摔,不是嗎?如果你嘗試了一下基本活動的指標上面的代碼赢赊,你可以輕松地創(chuàng)建各種效果乙漓,給一個試試吧!

3.跟隨動畫

在本教程中的第三個是有趣的跟隨動畫释移,您將指定的動畫原始圖層上的路徑叭披,并讓其拷貝在追逐,并視圖追第一個點玩讳。
切換到viewDidLoad中()

animation2()替換為:

func animation3()

正如你可能已經(jīng)猜到你的下一個步驟就是添加一個空的方法你最終的動畫:

func animation3(){ 

}

對于這個動畫涩蜘,您將需要添加另外一個方法。使用PaintCode應(yīng)用程序熏纯,可以快速創(chuàng)建了一個貝塞爾路徑同诫,你會用你的動畫。加入這個方法的ViewController

func rw() -> CGPath { 
    ////貝齊爾制圖
    變種bezierPath = UIBezierPath()
    bezierPath.moveToPoint(CGPointMake(31.5樟澜,71.5))
    bezierPath.addLineToPoint(CGPointMake(31.5误窖,23.5))
    bezierPath.addCurveToPoint(CGPointMake(58.5, 38.5)秩贰,
        controlPoint1:CGPointMake(31.5霹俺,23.5),
        controlPoint2:CGPointMake(62.46毒费,18.69))
    bezierPath.addCurveToPoint(CGPointMake(53.5吭服,45.5),
        controlPoint1:CGPointMake(57.5蝗罗,43.5)艇棕,
        controlPoint2:CGPointMake(53.5蝌戒,45.5))
    bezierPath.addLineToPoint(CGPointMake(43.5,48.5))
    bezierPath.addLineToPoint(CGPointMake(53.5沼琉,66.5))
    bezierPath.addLineToPoint(CGPointMake(62.5北苟,51.5))
    bezierPath.addLineToPoint(CGPointMake(70.5,66.5))
    bezierPath.addLineToPoint(CGPointMake( 86.5打瘪,23.5))
    bezierPath.addLineToPoint(CGPointMake(86.5友鼻,78.5))
    bezierPath.addLineToPoint(CGPointMake(31.5,78.5))
    bezierPath.addLineToPoint(CGPointMake(31.5闺骚,71.5))
    bezierPath.closePath()

    VAR T = CGAffineTransformMakeScale(3.0彩扔, 3.0)
    return CGPathCreateCopyByTransformingPath(bezierPath.CGPath,&T)
}

此方法創(chuàng)建的代碼貝塞爾路徑僻爽,并返回它的CGPath副本 - 這CGPath你會用它來創(chuàng)建一個關(guān)鍵幀動畫虫碉。
切換到到animation3() ,在里面添加代碼:

let r = CAReplicatorLayer()
r.bounds = view.bounds 
r.backgroundColor = UIColor(white:0.0,alapha:0.75).CGColor 
r.position = view.center 
view.layer.addSublayer(R)

這個時候我們創(chuàng)建并添加一個和視圖一樣大小的空復(fù)制層胸梆。首先我們需要添加原始層復(fù)制層
添加以下代碼:

let dot = CALayer()
dot.bounds = CGRect(0.0, 0.0, 10.0, 10.0)
dot.backgroundColor = UIColor(white: 0.8,alpha1.0).CGColor 
dot.borderColor = UIColor(white:1.0,alpha:1.0).CGColor 
dot.borderWidth = 1.0 
dot.cornerRadius = 5.0 
dot.shouldRasterize = true 
dot.rasterizationScale = UIScreen.mainScreen().scale
r.addSublayer(dot)

我們創(chuàng)建一個小銀矩形敦捧,并設(shè)置矩形寬度的一半為圓角半徑,所以你得到了一個小圈碰镜。我們對它進行復(fù)制兢卵。運行程序,我們將看到圓圈顯示在屏幕的左上角绪颖。

讓我們的動畫沿著路徑動起來:

let move = CAKeyframeAnimation(keyPath:"positon")
move.path = rw()
move.repeatCount = Float.infinity 
move.duration = 4.0 
dot.addAnimation(move秽荤,forKey:nil)

這個動畫沿著由rw()方法繪制的途徑,以4秒為周期柠横,不停的運動著窃款。

運行程序,現(xiàn)在我們會看到點像瘋了一樣亂跑滓鸠,看不到它所走過的路徑。
為了讓動畫更加清晰第喳,添加以下代碼:

r.instanceCount = 20 
r.instanceDelay = 0.1

這將增加的19個圓點糜俗,并讓他們跟著第一個運行:

酷!動畫開始運動就像你最喜歡的raywenderlich.comLogo一樣曲饱。

我們來模仿的更加像一點悠抹,首先讓顏色和raywenderlich.com網(wǎng)站的顏色的圓圈一樣。添加該代碼添加著色到復(fù)制的內(nèi)容:

r.instanceColor = UIColor(red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0).CGColor

設(shè)置instanceColor乘以您所提供的顏色原始內(nèi)容的顏色扩淀。在這種情況下楔敌,您將乘顏色鮮艷的綠色,所以如果你運行的應(yīng)用程序驻谆,你會看到一張很綠動畫:)))
有趣的是卵凑,你還可以改變instanceColor.它非常容易使得綠色的色調(diào)變得越來越黑加入這個代碼最后一行:

r.instanceGreenOffset = -0.03

這將使復(fù)制每次減少了0.03的綠色色調(diào)成分庆聘。最終的動畫看起來是這樣的:


會不會有人立刻打開一個新的Xcode項目,開始在一個貪吃蛇游戲呢勺卢?:]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末伙判,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子黑忱,更是在濱河造成了極大的恐慌宴抚,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件甫煞,死亡現(xiàn)場離奇詭異菇曲,居然都是意外死亡,警方通過查閱死者的電腦和手機抚吠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門常潮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人埃跷,你說我怎么就攤上這事蕊玷。” “怎么了弥雹?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵垃帅,是天一觀的道長。 經(jīng)常有香客問我剪勿,道長贸诚,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任厕吉,我火速辦了婚禮酱固,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘头朱。我一直安慰自己运悲,他們只是感情好,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布项钮。 她就那樣靜靜地躺著班眯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪烁巫。 梳的紋絲不亂的頭發(fā)上署隘,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機與錄音亚隙,去河邊找鬼磁餐。 笑死,一個胖子當著我的面吹牛阿弃,可吹牛的內(nèi)容都是我干的诊霹。 我是一名探鬼主播羞延,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼畅哑!你這毒婦竟也來了肴楷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤荠呐,失蹤者是張志新(化名)和其女友劉穎赛蔫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泥张,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡呵恢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了媚创。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片渗钉。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖钞钙,靈堂內(nèi)的尸體忽然破棺而出鳄橘,到底是詐尸還是另有隱情,我是刑警寧澤芒炼,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布瘫怜,位于F島的核電站,受9級特大地震影響本刽,放射性物質(zhì)發(fā)生泄漏鲸湃。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一子寓、第九天 我趴在偏房一處隱蔽的房頂上張望暗挑。 院中可真熱鬧,春花似錦斜友、人聲如沸炸裆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烹看。三九已至,卻和暖如春墙歪,著一層夾襖步出監(jiān)牢的瞬間听系,已是汗流浹背贝奇。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工虹菲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掉瞳。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓毕源,卻偏偏與公主長得像浪漠,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子霎褐,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

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