使用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動畫教程所 -你們是最棒的!
我希望,當(dāng)你通過這個月的教程中看到你會很高興,我把我的甜蜜的時間來準(zhǔn)備這些:]享受!

                                    ——- 馬林托多羅夫

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

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

當(dāng)我正在iOS的動畫教程由 CAReplicatorLayer在我的頭腦和我的主題列表了。然而,當(dāng)我們的計劃書,我們意識到并非所有的圖層將使其在和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在屏幕上的標(biāo)志在一個不尋常的方式:

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)準(zhǔn)備好與你最終的動畫!
接著來復(fù)制!添加以下代碼:

r.instanceCount = 3

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

r.instanceTransform = CATransform3DMakeTranslation(20.0,0.0,0.0)

這段代碼告訴復(fù)制圖層執(zhí)行怎樣的變換到內(nèi)容。您可以設(shè)置instanceTransform的值為偏移20每一個,當(dāng)您運行的應(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

如果你想不同的動畫就去改變instanceCountinstanceTransforminstanceDelay。很酷,不是嗎?

2.活動指示燈

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

animation2()

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

func animation2(){ 

}

在這部分教程你要創(chuàng)建活動指示器。為了好玩,我們將創(chuàng)建一個比內(nèi)置的iOS的活動指示器更精細(xì)的動畫。
首先添加一個復(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或者其他值來輕松的達(dá)到你想要的效果,復(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)

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

r.instanceDelay =duration/Double(nrDots)

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

dot.transform = CATransform3DMakeScale(0.01,0.01,0.01)。

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

做到這,是否感覺做動畫比想象中要簡單的多,不是嗎?如果你嘗試了一下基本活動的指標(biāo)上面的代碼,你可以輕松地創(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è)置矩形寬度的一半為圓角半徑,所以你得到了一個小圈。我們對它進(jìn)行復(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)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,006評論 2 374

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