Core Animation-1:圖層樹

来源:https://www.cnblogs.com/lfyDragon/archive/2018/03/21/8617902.html
-Advertisement-
Play Games

圖層的樹狀結構 >巨妖有圖層,洋蔥也有圖層,你懂嗎?我們都有圖層 -- 史萊克 Core Animation其實是一個令人誤解的命名。你可能認為它只是用來做動畫的,但實際上它是從一個叫做*Layer Kit*這麼一個不怎麼和動畫有關的名字演變而來,所以做動畫這隻是Core Animation特性的冰 ...


圖層的樹狀結構

>巨妖有圖層,洋蔥也有圖層,你懂嗎?我們都有圖層 -- 史萊克

Core Animation其實是一個令人誤解的命名。你可能認為它只是用來做動畫的,但實際上它是從一個叫做*Layer Kit*這麼一個不怎麼和動畫有關的名字演變而來,所以做動畫這隻是Core Animation特性的冰山一角。

Core Animation是一個*複合引擎*,它的職責就是儘可能快地組合屏幕上不同的可視內容,這個內容是被分解成獨立的*圖層*,存儲在一個叫做*圖層樹*的體系之中。於是這個樹形成了**UIKit**以及在iOS應用程式當中你所能在屏幕上看見的一切的基礎。

在我們討論動畫之前,我們將從圖層樹開始,涉及一下Core Animation的*靜態*組合以及佈局特性。

##圖層和視圖
如果你曾經在iOS或者Mac OS平臺上寫過應用程式,你可能會對*視圖*的概念比較熟悉。一個視圖就是在屏幕上顯示的一個矩形塊(比如圖片,文字或者視頻),它能夠攔截類似於滑鼠點擊或者觸摸手勢等用戶輸入。視圖在層級關係中可以互相嵌套,一個視圖可以管理它的所有子視圖的位置。圖1.1顯示了一種典型的視圖層級關係

 

圖1.1 一種典型的iOS屏幕(左邊)和形成視圖的層級關係(右邊)

在iOS當中,所有的視圖都從一個叫做`UIVIew`的基類派生而來,`UIView`可以處理觸摸事件,可以支持基於*Core Graphics*繪圖,可以做仿射變換(例如旋轉或者縮放),或者簡單的類似於滑動或者漸變的動畫。

###CALayer
`CALayer`類在概念上和`UIView`類似,同樣也是一些被層級關係樹管理的矩形塊,同樣也可以包含一些內容(像圖片,文本或者背景色),管理子圖層的位置。它們有一些方法和屬性用來做動畫和變換。和`UIView`最大的不同是`CALayer`不處理用戶的交互。

`CALayer`並不清楚具體的*響應鏈*(iOS通過視圖層級關係用來傳送觸摸事件的機制),於是它並不能夠響應事件,即使它提供了一些方法來判斷是否一個觸點在圖層的範圍之內(具體見第三章,“圖層的幾何學”)

###平行的層級關係
每一個`UIview`都有一個`CALayer`實例的圖層屬性,也就是所謂的*backing layer*,視圖的職責就是創建並管理這個圖層,以確保當子視圖在層級關係中添加或者被移除的時候,他們關聯的圖層也同樣對應在層級關係樹當中有相同的操作(見圖1.2)。

 

圖1.2 圖層的樹狀結構(左邊)以及對應的視圖層級(右邊)

實際上這些背後關聯的圖層才是真正用來在屏幕上顯示和做動畫,`UIView`僅僅是對它的一個封裝,提供了一些iOS類似於處理觸摸的具體功能,以及Core Animation底層方法的高級介面。

但是為什麼iOS要基於`UIView`和`CALayer`提供兩個平行的層級關係呢?為什麼不用一個簡單的層級來處理所有事情呢?原因在於要做職責分離,這樣也能避免很多重覆代碼。在iOS和Mac OS兩個平臺上,事件和用戶交互有很多地方的不同,基於多點觸控的用戶界面和基於滑鼠鍵盤有著本質的區別,這就是為什麼iOS有UIKit和`UIView`,但是Mac OS有AppKit和`NSView`的原因。他們功能上很相似,但是在實現上有著顯著的區別。

繪圖,佈局和動畫,相比之下就是類似Mac筆記本和桌面系列一樣應用於iPhone和iPad觸屏的概念。把這種功能的邏輯分開並應用到獨立的Core Animation框架,蘋果就能夠在iOS和Mac OS之間共用代碼,使得對蘋果自己的OS開發團隊和第三方開發者去開發兩個平臺的應用更加便捷。

實際上,這裡並不是兩個層級關係,而是四個,每一個都扮演不同的角色,除了視圖層級和圖層樹之外,還存在*呈現樹*和*渲染樹*,將在第七章“隱式動畫”和第十二章“性能調優”分別討論。

###圖層的能力
如果說`CALayer`是`UIView`內部實現細節,那我們為什麼要全面地瞭解它呢?蘋果當然為我們提供了優美簡潔的`UIView`介面,那麼我們是否就沒必要直接去處理Core Animation的細節了呢?

某種意義上說的確是這樣,對一些簡單的需求來說,我們確實沒必要處理`CALayer`,因為蘋果已經通過`UIView`的高級API間接地使得動畫變得很簡單。

但是這種簡單會不可避免地帶來一些靈活上的缺陷。如果你略微想在底層做一些改變,或者使用一些蘋果沒有在`UIView`上實現的介面功能,這時除了介入Core Animation底層之外別無選擇。

我們已經證實了圖層不能像視圖那樣處理觸摸事件,那麼他能做哪些視圖不能做的呢?這裡有一些`UIView`沒有暴露出來的CALayer的功能:

* 陰影,圓角,帶顏色的邊框
* 3D變換
* 非矩形範圍
* 透明遮罩
* 多級非線性動畫

我們將會在後續章節中探索這些功能,首先我們要關註一下在應用程式當中`CALayer`是怎樣被利用起來的。

##使用圖層
首先我們來創建一個簡單的項目,來操縱一些`layer`的屬性。打開Xcode,使用*Single View Application*模板創建一個工程。

在屏幕中央創建一個小視圖(大約200 X 200的尺寸),當然你可以手工編碼,或者使用Interface Builder(隨你方便)。確保你的視圖控制器要添加一個視圖的屬性以便可以直接訪問它。我們把它稱作`layerView`。

運行項目,應該能在淺灰色屏幕背景中看見一個白色方塊(圖1.3),如果沒看見,可能需要調整一下背景window或者view的顏色

 

圖1.3 灰色背景上的一個白色`UIView`

這並沒有什麼令人激動的地方,我們來添加一個色塊,在白色方塊中間添加一個小的藍色塊。

我們當然可以簡單地在已經存在的`UIView`上添加一個子視圖(隨意用代碼或者IB),但這不能真正學到任何關於圖層的東西。

於是我們來創建一個`CALayer`,並且把它作為我們視圖相關圖層的子圖層。儘管`UIView`類的介面中暴露了圖層屬性,但是標準的Xcode項目模板並沒有包含Core Animation相關頭文件。所以如果我們不給項目添加合適的庫,是不能夠使用任何圖層相關的方法或者訪問它的屬性。所以首先需要添加QuartzCore框架到Build Phases標簽(圖1.4),然後在vc的.m文件中引入<QuartzCore/QuartzCore.h>庫。

<img src="./1.4.jpeg" alt="圖1.4" title="圖1.4" width="700"/>

圖1.4 把QuartzCore庫添加到項目

之後就可以在代碼中直接引用`CALayer`的屬性和方法。在清單1.1中,我們用創建了一個`CALayer`,設置了它的`backgroundColor`屬性,然後添加到`layerView`背後相關圖層的子圖層(這段代碼的前提是通過IB創建了`layerView`並做好了連接),圖1.5顯示了結果。

清單1.1 給視圖添加一個藍色子圖層
``` objective-c
#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>
@interface ViewController ()

@property (nonatomic, weak) IBOutlet UIView *layerView;

@end

@implementation ViewController

- (void)viewDidLoad
{
[super viewDidLoad];
//create sublayer
CALayer *blueLayer = [CALayer layer];
blueLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
//add it to our view
[self.layerView.layer addSublayer:blueLayer];
}
@end
```

 

圖1.5 白色`UIView`內部嵌套的藍色`CALayer`

一個視圖只有一個相關聯的圖層(自動創建),同時它也可以支持添加無數多個子圖層,從清單1.1可以看出,你可以顯示創建一個單獨的圖層,並且把它直接添加到視圖關聯圖層的子圖層。儘管可以這樣添加圖層,但往往我們只是見簡單地處理視圖,他們關聯的圖層並不需要額外地手動添加子圖層。

在Mac OS平臺,10.8版本之前,一個顯著的性能缺陷就是由於用了視圖層級而不是單獨在一個視圖內使用`CALayer`樹狀層級。但是在iOS平臺,使用輕量級的`UIView`類並沒有顯著的性能影響(當然在Mac OS 10.8之後,`NSView`的性能同樣也得到很大程度的提高)。

使用圖層關聯的視圖而不是`CALayer`的好處在於,你能在使用所有`CALayer`底層特性的同時,也可以使用`UIView`的高級API(比如自動排版,佈局和事件處理)。

然而,當滿足以下條件的時候,你可能更需要使用`CALayer`而不是`UIView`

* 開發同時可以在Mac OS上運行的跨平臺應用
* 使用多種`CALayer`的子類(見第六章,“特殊的圖層“),並且不想創建額外的`UIView`去包封裝它們所有
* 做一些對性能特別挑剔的工作,比如對`UIView`一些可忽略不計的操作都會引起顯著的不同(儘管在這種情況下,你可能會想直接使用OpenGL來繪圖)


但是這些例子都很少見,總的來說,處理視圖會比單獨處理圖層更加方便。

##總結
這一章闡述了圖層的樹狀結構,說明瞭如何在iOS中由`UIView`的層級關係形成的一種平行的`CALayer`層級關係,在後面的實驗中,我們創建了自己的`CALayer`,並把它添加到圖層樹中。

在第二章,“圖層關聯的圖片”,我們將要研究一下`CALayer`關聯的圖片,以及Core Animation提供的操作顯示的一些特性。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文為mariadb官方手冊:賦值操作符(:=)的譯文。 原文:https://mariadb.com/kb/en/assignment-operator/ 我提交到MariaDB官方手冊的譯文:https://mariadb.com/kb/zh-cn/assignment-operator/ 語法 ...
  • 前言 我們都知道,hbase是一個很有潛力的NoSql(Not Only Sql),1970年 E.F.Codd's提出的關係模型的論文 "A relational model of data for large shared data banks",這使得數據建模和應用程式編程更加簡單。 通過應用 ...
  • Oracle帳號:[email protected] Oracle密碼:Oracle123 ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
  • 簡要:本系列文章講會對expo進行全面的介紹,本人從2017年6月份接觸expo以來,對expo的研究斷斷續續,一路走來將近10個月,廢話不多說,接下來你看到內容,講全部來與官網 我猜去全部機翻+個人修改補充+demo測試的形式,對expo進行一次大補血!歡迎加入expo興趣學習交流群:597732 ...
  • 一、Android 系統架構 Android 系統架構分為四層:Linux 內核層、系統庫層、應用框架層、應用層 1. Linux 內核層(Linux Kernel) 這一層提供的功能有:安全性、記憶體管理、進程管理、網路協議棧、驅動程式模型等 2. 系統庫層(Libraries) 這一層包括兩方面的 ...
  • 最近,我在HorizontalScrollview中使用scrollTo不起作用? ...... 以上省略N個字。 我只想說: 在使用scrollTo的時候,要先保證該HorizontalScrollview已經初始化完畢,要是無法保證,那麼,可以在HorizontalScrollview中這樣寫 ...
  • Swift,是蘋果於2014年WWDC(蘋果開發者大會)發佈的新開發語言,可與Objective-C共同運行於Mac OS和iOS平臺,用於搭建基於蘋果平臺的應用程式。它是一款易學易用的編程語言,而且它還是第一套具有與腳本語言同樣的表現力和趣味性的系統編程語言。Swift的設計以安全為出發點,以避免 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...