CALayer 新手指南

做者:Pranjal Satija,原文連接,原文日期:2016-08-16
譯者:Cwift;校對:Cee;定稿:CMBhtml

歡迎!這篇文章將教你一項 iOS 中的關鍵技術:圖層(layer)。你可能已經知道了 iOS 中的視圖,但你可能不知道每個獨立的視圖背後都有稱爲圖層的東西。圖層是 Core Animation 框架中的內容。git

你也許很好奇,「我歷來沒有用過一個圖層,因此它可能沒那麼重要吧?」不管你知道與否,你的應用程序都會大量使用圖層。不論是什麼視圖,iOS 上的視圖都會包含一個圖層。正是由於圖層的存在,iOS 能夠在你的應用中輕鬆檢測到視圖的位圖信息,而後提供給設備的 GPU。請參照下面的圖片(來自蘋果公司),清晰地展現了 Core Animation 在 iOS 層次結構中的位置。github

爲何使用圖層?

在智能手機等設備上,用戶但願他們的一切操做都很快。保持連貫的幀速率很關鍵,這樣用戶纔會以爲「絲滑流暢」。在 iOS 中,幀速率是每秒 60 幀。爲了保持系統能在這個速率下運做,一個直接運行在 GPU 上、很是基礎可是功能強大的圖形功能層誕生了,它就是 OpenGLswift

OpenGL 提供了大部分底層的(並且是最快的)訪問權限,直達 iOS 設備的圖像硬件。然而你須要作出權衡:OpenGL 太靠近底層了,即使是爲了完成最簡單的任務,都須要大量的代碼。app

爲了可以緩解這個問題,蘋果建立了 Core Graphics,它提供了更高級一些的方法,代碼量也隨之更少。使用 Core Graphics 的初衷是應用到一些比較底層的功能上。爲了使 Core Graphics 的使用更簡單,蘋果建立了 Core Animation。它提供了 CALayer 類,而且容許一些基本的底層圖像操做。框架

當蘋果認爲 Core Animation 中的不少高級高級功能在常規應用中並不老是須要的時候,UIKit 就誕生了,它提供了 iOS 中最頂層的圖像訪問權限。此設計方案的優勢是,在你的應用中,你能夠選擇你須要的圖像訪問級別而且應用它,容許你挑選並精準地選擇所須要的功能量級,使你沒必要編寫無用的代碼。
缺點是較高級別的圖形 API 提供的功能比較少。講這個故事是爲了說明:由於 CALayer 的存在,iOS 系統能夠洞悉你的應用中的視圖層次結構,快速生成層次結構的位圖信息,而後將其傳遞到 Core Graphics 中去,最終到達 OpenGL,這樣經過設備的 GPU 處理後圖像就呈如今屏幕上了。儘管在大多數狀況下都不須要直接使用 CALayer,可是較爲底層的 API 爲用戶提供了一些更靈活的自定義方案,咱們將在本文中討論。性能

訪問 CALayer

關於圖層的存在原因已經討論的夠多了。讓咱們動起手來!正如我上面提到的同樣,每個視圖都有一個圖層來支持,能夠經過 UIViewlayer 屬性訪問。假設你有一個 myView 對象,你能夠像下面這樣訪問它的 layer:學習

myView.layer

好了,咱們可以訪問圖層了,能夠用它作些什麼呢?你會驚訝地發現有很是多能夠作的事情。我會在本教程的剩餘部分展現其中的一部分技巧和效果。動畫

示例工程

首先,打開模板工程,讓咱們正式開始吧!學習的最佳途徑是動手,因此咱們將向這個應用中的視圖添加自定義的效果。打開工程,你會發現它至關簡單。它是一個空白的白色視圖,中心有一個正方形的黑色子視圖。讓咱們把它修飾得美觀一點。打開示例工程,跳轉到 ViewController.swift,正式開始。網站

建立圓角

你可使用 CALayercornerRadius 屬性來設定圖層邊緣的圓角。讓咱們試試看。在 viewDidLoad() 中添加如下代碼:

box.layer.cornerRadius = 5

如預期的同樣,這行代碼將會給 box 的圖層增長一個半徑爲 5 的圓角。看起來像這樣:

不算太壞,對吧?對於拐角大的圖形須要增長圓角的半徑,對於拐角小的圖形減少圓角的半徑。默認的,全部圖層的圓角半徑都是 0。

添加陰影效果

陰影能夠幫助咱們在咱們的應用中建立出深度的感受,在界面設計中很是實用。使用陰影效果,可使視圖「浮動」在屏幕上。讓咱們來看看如何使用 CALayer 建立一個陰影效果。把下面的代碼加到 ViewControllerviewDidLoad 方法中:

box.layer.shadowOffset = CGSizeMake(5, 5)
box.layer.shadowOpacity = 0.7
box.layer.shadowRadius = 5
box.layer.shadowColor = UIColor(red: 44.0/255.0, green: 62.0/255.0, blue: 80.0/255.0, alpha: 1.0).CGColor

第一行:這一行設置圖層陰影的偏移量爲(5,5)。 layer.shadowOffset 中接受一個 CGSize 類型的參數。向 layer.shadowOffset 中傳入(5,5)意味着圖層的陰影出如今 box.layer 右側 5 個點以及下方 5 個點連成的區域上。

第二行:這一行將圖層陰影的不透明度設爲 0.7。這意味着陰影應該是 70% 不透明的。

第三行:這一行將圖層陰影的範圍設爲 5。陰影的範圍表明了 box.layer 所建立的陰影的模糊範圍。更高的範圍值意味着陰影會更加擴散,可是可視度會下降。較低的範圍值使得陰影更加顯眼和集中。陰影範圍爲0會致使根本不會有模糊。換句話說,這使得陰影與圖層保持徹底相同的尺寸和形狀。

第四行:這一行設置圖層陰影的顏色爲午夜藍。注意這個屬性是 CGColor 類型的,而不是一個 UIColor。在兩種類型之間轉換很是容易。你只要寫 myUIColor.CGColor就能夠啦。


讓咱們來看一下效果!

應用邊框

CALayer 還容許咱們輕鬆地使用邊框。讓咱們給 box 增長一個邊框。

box.layer.borderColor = UIColor.blueColor().CGColor
box.layer.borderWidth = 3

第一行:這一行把邊框的顏色設置爲午夜藍。這會使得 box 上的任何邊框都呈現出藍色。

第二行:這一行設置邊框的寬度爲 3。這意味着 box 周圍繪製的邊框將有 3 個點的厚度。

讓咱們看看增長了邊框的 box 是什麼樣子。

顯示圖像

你還能夠把一個圖片分配給圖層,以便在圖層上展現圖片。在示例工程中有一個可愛的樹的圖片,感謝這個網站。讓咱們用圖層來展現這張圖片。在 viewDidLoad 中加入如下代碼:

box.layer.contents = UIImage(named: "tree.jpg")?.CGImage
box.layer.contentsGravity = kCAGravityResize
box.layer.masksToBounds = true

第一行:這一行使用文件名 tree.jpg 建立了一個 UIImage 對象,而後把它傳給了圖層的 contents 屬性。

第二行:這一行設置圖層的內容重心來調整大小,這意味着圖層中的全部內容將被調整大小以便完美地適應圖層的尺寸。

第三行:咱們設置 masksToBoundstrue,以便圖層中任何延伸到邊界外的子圖層都會在邊界處被剪裁。若是你不明白這句話的含義,你能夠把這個值設置爲 false,而後查看效果。

下面是效果。

背景色和不透明度

咱們已經討論過了如何向 CALayer 中添加那些在 UIKit中沒法實現的特殊效果,但咱們還應該討論一下如何經過 CALayer 修改 UIKit 暴露給 UIView 的大部分屬性。例如你能夠改變視圖的背景顏色和不透明度:

box.layer.backgroundColor = UIColor.blueColor().CGColor
box.layer.opacity = 0.5

CALayer 的性能

向圖層添加大量自定義效果可能會對性能產生影響。如今,咱們將討論 CALayer 的兩個屬性,它們能夠幫助咱們大幅度提升應用程序的性能。

首先,讓咱們來討論下 drawsAsynchronously。這是屬性在 CALayer 上指定了在繪製圖層時 CPU 必須執行的那些操做是否須要在後臺線程中執行的做用。若是這個屬性被設置爲 true,圖層看起來與往常同樣,可是繪製它所需的 CPU 計算將在後臺線程中執行。若是你的應用中有一個須要大量從新繪製的視圖(例如地圖視圖或表格視圖),請將此項設爲 true

另外一個屬性是 shouldRasterize。這是 CALayer 上的另外一個屬性。它指定了是否應該對圖層進行光柵化。當這個屬性被設置爲 true 的時候,圖層只被繪製一次。每當圖層被動畫化的時候,圖層不會被重繪,而是不斷複用第一次繪製時的位圖信息。若是你的應用中有一個視圖不須要頻繁重繪,則應將這個屬性設置爲 true。注意,當設置 shouldRasterize 時,圖層的外觀可能會在 Retina 屏幕的設備上有所不一樣。這是由於圖層存在所謂的光柵化比例,這個比例用在圖層發生光柵化的時候。要防止這種狀況發生,把圖層的 rasterizationScale 設置爲 UIScreen.mainScreen().scale,這樣在圖層進行光柵化的時候會與屏幕繪製的比例保持一致。

注意,99% 的狀況下你都不須要本身去設置這些屬性。手動設置它們可能致使性能低下。若是你能肯定視圖或圖層的繪製正在影響應用程序的性能,你也只能自行設置這兩個屬性中的一個。

結論

如今你知道 CALayer 是什麼了!瞭解一些比較底層的圖像知識能夠幫助你在你的應用中建立一些很酷的效果。但願你喜歡這個新手指南。

做爲參考,你能夠在 GitHub 上下載這個示例工程。若是你有任何問題或者反饋,請在下面給我留言。

本文由 SwiftGG 翻譯組翻譯,已經得到做者翻譯受權,最新文章請訪問 http://swift.gg

相關文章
相關標籤/搜索