[toc]
前言
Core Animation
提供了一種通用系統(tǒng)享潜,可對(duì)應(yīng)用程序的視圖和其他視覺元素進(jìn)行動(dòng)畫處理潘懊。Core Animation
不能替代您的應(yīng)用程序視圖狼电。相反,它是一種與視圖集成以提供更好的性能和動(dòng)畫效果的技術(shù)盆均。它通過將視圖的內(nèi)容緩存到可以由圖形硬件直接操縱的位圖中來實(shí)現(xiàn)此行為塞弊。在某些情況下,這種緩存行為可能需要您重新考慮如何呈現(xiàn)和管理應(yīng)用程序的內(nèi)容泪姨,但是大多數(shù)情況下游沿,您在不知道它存在的情況下使用Core Animation
。除了緩存視圖內(nèi)容之外肮砾,Core Animation
還定義了一種方法诀黍,該方法可以指定任意視覺內(nèi)容,將該內(nèi)容與視圖集成以及將其與其他所有內(nèi)容一起設(shè)置為動(dòng)畫
核心動(dòng)畫知識(shí)
從圖中可以看出仗处,最底層是圖形硬件
(GPU)
眯勾;上層是OpenGL
和CoreGraphics
,提供一些接口來訪問GPU婆誓;再上層的CoreAnimation
在此基礎(chǔ)上封裝了一套動(dòng)畫的API吃环。最上面的UIKit
屬于應(yīng)用層,處理與用戶的交互洋幻。所以郁轻,學(xué)習(xí)這CoreAnimation`也會(huì)涉及一些圖形學(xué)的知識(shí),了解這些有助于我們更順手的使用以及更高效的解決問題文留。
- Core Animation 結(jié)構(gòu)圖
Core Animation Introduction
- 簡單易易?用的?高性能混合編程模型
- ?用類似于視圖?一樣,使?用圖層來創(chuàng)建復(fù)雜的編程接?口
- 輕量量化的數(shù)據(jù)結(jié)構(gòu),它可以同時(shí)顯示讓上百個(gè)圖層產(chǎn)?生動(dòng)畫效果
- 一套?非常較簡單的動(dòng)畫接?口,能讓動(dòng)畫運(yùn)?行行在獨(dú)?立的線程中,并可以獨(dú)?立于主線程之外.
- 一旦動(dòng)畫配置完成并啟動(dòng),核?心動(dòng)畫就能獨(dú)?立并完全控制相應(yīng)的動(dòng)畫幀.
- 提?高應(yīng)?用性能.應(yīng)?用程序只有當(dāng)發(fā)?生改變的時(shí)候才會(huì)重繪內(nèi)容. 使?用
Core Animation
可以不不使?用其他圖形API
,例例如OpenGL
來獲取?高效的動(dòng)畫性能. - . 靈活的布局管理理模型,允許圖層相對(duì)同級(jí)圖層的關(guān)系來設(shè)置屬性的位置和?大?小
核心動(dòng)畫圖層樹結(jié)構(gòu)
使用
Core Animation
的應(yīng)用程序具有三組
圖層對(duì)象.
-
圖層樹
是最的那些您的應(yīng)用程序進(jìn)行交互好唯。該樹中的對(duì)象是存儲(chǔ)任何動(dòng)畫的目標(biāo)值的模型對(duì)象。每當(dāng)更改圖層的屬性時(shí)燥翅,都將使用這些對(duì)象之一渠啊。 -
呈現(xiàn)樹
中的對(duì)象包含任何正在運(yùn)行的動(dòng)畫的運(yùn)行中值。圖層樹對(duì)象包含動(dòng)畫的目標(biāo)值权旷,而表示樹中的對(duì)象則反映屏幕上顯示的當(dāng)前值替蛉。您永遠(yuǎn)不要修改此樹中的對(duì)象贯溅。相反,您可以使用這些對(duì)象讀取當(dāng)前動(dòng)畫值躲查,也許可以從這些值開始創(chuàng)建新動(dòng)畫它浅。 -
渲染樹
中的對(duì)象執(zhí)行實(shí)際的動(dòng)畫,并且是Core Animation
專有的镣煮。
與窗口關(guān)聯(lián)的圖層樹
三組圖層對(duì)象
圖層與視圖
一個(gè)視圖就是在屏幕上顯示的一個(gè)矩形塊
(比如圖片姐霍,文字或者視頻),它能夠攔截類似于鼠標(biāo)點(diǎn)擊或者觸摸手勢(shì)等用戶輸入典唇。視圖在層級(jí)關(guān)系中可以互相嵌套镊折,一個(gè)視圖可以管理它的所有子視圖的位置
.
在
iOS
當(dāng)中,所有的視圖都從一個(gè)叫做UIVIew
的基類派生而來介衔,UIView
可以處理觸摸事件恨胚,可以支持基于Core Graphics
繪圖,可以做仿射變換(例如旋轉(zhuǎn)或者縮放)炎咖,或者簡單的類似于滑動(dòng)或者漸變的動(dòng)畫赃泡。
圖層與視圖之間的關(guān)系
圖層不能替代
您應(yīng)用程序的視圖
,也就是說乘盼,您不能僅基于圖層對(duì)象創(chuàng)建可視界面升熊。圖層為您的視圖提供基礎(chǔ)結(jié)構(gòu)。特別是绸栅,圖層使繪制和動(dòng)畫化視圖內(nèi)容并使其保持動(dòng)畫狀態(tài)并保持較高的幀速率更加容易和有效级野。但是,許多事情是圖層無法做到的粹胯。層不處理事件蓖柔,繪制內(nèi)容,參與響應(yīng)者鏈或執(zhí)行其他許多事情矛双。因此,每個(gè)應(yīng)用程序仍必須具有一個(gè)或多個(gè)視圖來處理這些類型的交互.
CALayer
CALayer
類在概念上和UIView
類似蟆豫,同樣也是一些被層級(jí)關(guān)系樹管理的矩形塊议忽,同樣也可以包含一些內(nèi)容(像圖片,文本或者背景色)十减,管理子圖層的位置栈幸。它們有一些方法和屬性用來做動(dòng)畫和變換。和UIView
最大的不同是CALayer
不處理用戶的交互帮辟。
CALayer
并不清楚具體的響應(yīng)鏈(iOS
通過視圖層級(jí)關(guān)系用來傳送觸摸事件的機(jī)制)速址,于是它并不能夠響應(yīng)事件,即使它提供了一些方法來判斷是否一個(gè)觸點(diǎn)在圖層的范圍之內(nèi)
.
平行的層級(jí)關(guān)系
每一個(gè)UIview
都有一個(gè)CALayer
實(shí)例的圖層屬性由驹,也就是所謂的backing layer
芍锚,視圖的職責(zé)就是創(chuàng)建并管理這個(gè)圖層,以確保當(dāng)子視圖在層級(jí)關(guān)系中添加或者被移除的時(shí)候,他們關(guān)聯(lián)的圖層也同樣對(duì)應(yīng)在層級(jí)關(guān)系樹當(dāng)中有相同的操作
.
實(shí)際上這些背后關(guān)聯(lián)的圖層才是真正用來在屏幕上顯示和做動(dòng)畫并炮,
UIView
僅僅是對(duì)它的一個(gè)封裝默刚,提供了一些iOS類似于處理觸摸的具體功能,以及Core Animation
底層方法的高級(jí)接口.
但是為什么iOS要基于UIView和CALayer提供兩個(gè)平行的層級(jí)關(guān)系呢?
為什么不用一個(gè)簡單的層級(jí)來處理所有事情呢逃魄?
原因在于要做職責(zé)分離
荤西,這樣也能避免很多重復(fù)代碼。在iOS
和Mac OS
兩個(gè)平臺(tái)上伍俘,事件和用戶交互有很多地方的不同邪锌,基于多點(diǎn)觸控的用戶界面和基于鼠標(biāo)鍵盤有著本質(zhì)的區(qū)別,這就是為什么iOS
有UIKit
和UIView
癌瘾,但是Mac OS
有AppKit
和NSView
的原因觅丰。他們功能上很相似,但是在實(shí)現(xiàn)上有著顯著的區(qū)別
圖層的能力
我們已經(jīng)證實(shí)了圖層不能像視圖那樣處理觸摸事件柳弄,那么他能做哪些視圖不能做的呢舶胀?這里有一些UIView
沒有暴露出來的CALayer
的功能:
- 陰影,圓角碧注,帶顏色的邊框
-
3D
變換 - 非矩形范圍
- 透明遮罩
- 多級(jí)非線性動(dòng)畫
簡單使用圖層
在屏幕上添加一個(gè)藍(lán)色view,可以通過設(shè)置CALayer
的backgroundColor
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(100, 100, 100, 100);
layer.backgroundColor = [UIColor greenColor].CGColor;
_layer = layer;
[self.view.layer addSublayer:layer];
然而嚣伐,當(dāng)滿足以下條件的時(shí)候,你可能更需要使用CALayer
而不是UIView
:
- 開發(fā)同時(shí)可以在
Mac OS
上運(yùn)行的跨平臺(tái)應(yīng)用 - 使用多種
CALayer
的子類(見第六章萍丐,“特殊的圖層“)轩端,并且不想創(chuàng)建額外的UIView
去包封裝它們所有 - 做一些對(duì)性能特別挑剔的工作,比如對(duì)
UIView
一些可忽略不計(jì)的操作都會(huì)引起顯著的不同(盡管如此逝变,你可能會(huì)直接想使用OpenGL繪圖)
CALayer 常用屬性詳解
contents
CALayer
有一個(gè)屬性叫做contents
基茵,這個(gè)屬性的類型被定義為id,意味著它可以是任何類型的對(duì)象壳影。在這種情況下拱层,你可以給contents
屬性賦任何值,你的app
仍然能夠編譯通過宴咧。但是根灯,在實(shí)踐中,如果你給contents
賦的不是CGImage
掺栅,那么你得到的圖層將是空白的烙肺。
- 如果要給圖層的寄宿圖賦值
UIImage *image = [UIImage imageNamed:@"test.png"];
//add it directly to our view's layer
self.layerView.layer.contents = (__bridge id)image.CGImage;
contents
這個(gè)奇怪的表現(xiàn)是由Mac OS
的歷史原因造成的。它之所以被定義為id
類型氧卧,是因?yàn)樵?code>Mac OS系統(tǒng)上桃笙,這個(gè)屬性對(duì)CGImage
和NSImage
類型的值都起作用。如果你試圖在iOS
平臺(tái)上將UIImag
e的值賦給它沙绝,只能得到一個(gè)空白的圖層搏明。一些初識(shí)Core Animation
的iOS
開發(fā)者可能會(huì)對(duì)這個(gè)感到困惑
contentsGravity
CALayer
與contentMode
對(duì)應(yīng)的屬性叫做contentsGravity
鼠锈,但是它是一個(gè)NSString
類型,而不是像對(duì)應(yīng)的UIKit
部分熏瞄,那里面的值是枚舉脚祟。contentsGravity
可選的常量值有以下一些:
* kCAGravityCenter
* kCAGravityTop
* kCAGravityBottom
* kCAGravityLeft
* kCAGravityRight
* kCAGravityTopLeft
* kCAGravityTopRight
* kCAGravityBottomLeft
* kCAGravityBottomRight
* kCAGravityResize
* kCAGravityResizeAspect
* kCAGravityResizeAspectFill
- 使用
self.layerView.layer.contentsGravity = kCAGravityResizeAspect;
contentsScale
contentsScale
屬性定義了寄宿圖的像素尺寸和視圖大小的比例,默認(rèn)情況下它是一個(gè)值為1.0的浮點(diǎn)數(shù)强饮。
如果contentsScale
設(shè)置為1.0
由桌,將會(huì)以每個(gè)點(diǎn)1
個(gè)像素繪制圖片,如果設(shè)置為2.0
邮丰,則會(huì)以每個(gè)點(diǎn)2
個(gè)像素繪制圖片行您,這就是我們熟知的Retina
屏幕。
- 使用
當(dāng)我們使用
UIImage
類去讀取我們的雪人圖片的時(shí)候剪廉,他讀取了高質(zhì)量的Retina
版本的圖片娃循。但是當(dāng)我們用CGImage
來設(shè)置我們的圖層的內(nèi)容時(shí),拉伸這個(gè)因素在轉(zhuǎn)換的時(shí)候就丟失了斗蒋。不過我們可以通過手動(dòng)設(shè)置contentsScale
來修復(fù)這個(gè)問題
//set the contentsScale to match image
self.layerView.layer.contentsScale = image.scale;
maskToBounds
UIView
有一個(gè)叫做clipsToBounds
的屬性可以用來決定是否顯示超出邊界的內(nèi)容捌斧,CALayer
對(duì)應(yīng)的屬性叫做masksToBounds
.
contentsRect
CALayer
的contentsRect
屬性允許我們?cè)趫D層邊框里顯示寄宿圖的一個(gè)子域。這涉及到圖片是如何顯示和拉伸的泉沾,所以要比contentsGravity
靈活多了
和bounds
捞蚂,frame
不同,contentsRect
不是按點(diǎn)來計(jì)算的跷究,它使用了單位坐標(biāo)姓迅,單位坐標(biāo)指定在0
到1
之間,是一個(gè)相對(duì)值(像素和點(diǎn)就是絕對(duì)值)俊马。所以他們是相對(duì)與寄宿圖的尺寸的丁存。iOS使用了以下的坐標(biāo)系統(tǒng):
點(diǎn) —— 在
iOS
和Mac OS
中最常見的坐標(biāo)體系。點(diǎn)就像是虛擬的像素柴我,也被稱作邏輯像素解寝。在標(biāo)準(zhǔn)設(shè)備上,一個(gè)點(diǎn)就是一個(gè)像素艘儒,但是在Retina
設(shè)備上聋伦,一個(gè)點(diǎn)等于2*2
個(gè)像素。iOS
用點(diǎn)作為屏幕的坐標(biāo)測(cè)算體系就是為了在Retina
設(shè)備和普通設(shè)備上能有一致的視覺效果彤悔。像素 —— 物理像素坐標(biāo)并不會(huì)用來屏幕布局嘉抓,但是仍然與圖片有相對(duì)關(guān)系索守。
UIImage
是一個(gè)屏幕分辨率解決方案晕窑,所以指定點(diǎn)來度量大小。但是一些底層的圖片表示如CGImage
就會(huì)使用像素卵佛,所以你要清楚在Retina
設(shè)備和普通設(shè)備上杨赤,他們表現(xiàn)出來了不同的大小敞斋。單位 —— 對(duì)于與圖片大小或是圖層邊界相關(guān)的顯示,單位坐標(biāo)是一個(gè)方便的度量方式疾牲, 當(dāng)大小改變的時(shí)候植捎,也不需要再次調(diào)整。單位坐標(biāo)在
OpenGL
這種紋理坐標(biāo)系統(tǒng)中用得很多阳柔,Core Animation
中也用到了單位坐標(biāo)焰枢。
默認(rèn)的contentsRect是{0, 0, 1, 1},這意味著整個(gè)寄宿圖默認(rèn)都是可見的舌剂,如果我們指定一個(gè)小一點(diǎn)的矩形济锄,圖片就會(huì)被裁剪
contentsCenter
contentsCenter
其實(shí)是一個(gè)CGRect
,它定義了一個(gè)固定的邊框和一個(gè)在圖層上可拉伸的區(qū)域霍转。
self.view.layer.contentsCenter = CGRectMake(0, 0, 1, 1);
self.view.layer.contentsCenter = CGRectMake(0, 0, 0.5, 0.5);
圖層幾何學(xué)
UIView
有三個(gè)比較重要的布局屬性:frame
荐绝,bounds
和center
,CALayer
對(duì)應(yīng)地叫做frame
避消,bounds
和position
低滩。為了能清楚區(qū)分,圖層用了“position”
岩喷,視圖用了“center”
恕沫,但是他們都代表同樣的值。
如圖:
anchorPoint
圖層的anchorPoint
通過position
來控制它的frame
的位置均驶,你可以認(rèn)為anchorPoint是用來移動(dòng)圖層的把柄昏兆。
anchorPoint
相當(dāng)于支點(diǎn),可以用作旋轉(zhuǎn)變化妇穴、平移爬虱、縮放.
如果修改anchorPoint
則layer
的frame
會(huì)發(fā)生改變,position
不會(huì)發(fā)生改變.修改position
與anchorPoint
中任何一個(gè)屬性都不影響另一個(gè)屬性.
- 視圖frame計(jì)算公式:
frame.origin.x = position.x - anchorPoint.x * bounds.size.width腾它;
frame.origin.y = position.y - anchorPoint.y * bounds.size.height跑筝;
坐標(biāo)系
Core Graphics
源于Mac OS X
系統(tǒng),在Mac OS X中瞒滴,坐標(biāo)原點(diǎn)在左下方并且正
y坐標(biāo)是朝上的曲梗,而在
iOS中,原點(diǎn)坐標(biāo)是在左上方并且正
y坐標(biāo)是朝下的妓忍。在大多數(shù)情況下虏两,這不會(huì)出現(xiàn)任何問題,因?yàn)閳D形上下文的坐標(biāo)系統(tǒng)是會(huì)自動(dòng)調(diào)節(jié)補(bǔ)償?shù)氖榔省5莿?chuàng)建和繪制一個(gè)
CGImage`對(duì)象時(shí)就會(huì)暴露出倒置問題.
ZPosition
和UIView
嚴(yán)格的二維坐標(biāo)系不同定罢,CALayer
存在于一個(gè)三維空間當(dāng)中。除了我們已經(jīng)討論過的position
和anchorPoint
屬性之外旁瘫,CALayer
還有另外兩個(gè)屬性祖凫,zPosition
和anchorPointZ
琼蚯,二者都是在Z
軸上描述圖層位置的浮點(diǎn)類型。
此屬性的默認(rèn)值為0
惠况。更改此屬性的值會(huì)更改屏幕上各層的從前到后的順序遭庶。較高的值比較低的值在視覺上更靠近該圖層
CALayer中HitTest屬性的實(shí)際使用
響應(yīng)者對(duì)象(Responder Object
),顧名思義稠屠,指的是有響應(yīng)和處理事件能力的對(duì)象峦睡。響應(yīng)者鏈就是由一系列的響應(yīng)者對(duì)象構(gòu)成的一個(gè)層次結(jié)構(gòu)。
第一響應(yīng)者(First responder
)指的是當(dāng)前接受觸摸的響應(yīng)者對(duì)象(通常是一個(gè)UIView
對(duì)象)权埠,即表示當(dāng)前該對(duì)象正在與用戶交互赐俗,它是響應(yīng)者鏈的開端。整個(gè)響應(yīng)者鏈和事件分發(fā)的使命都是找出第一響應(yīng)者弊知。
-
hitTest:withEven:
方法的處理流程如下
1. 首先調(diào)用當(dāng)前視圖的
pointInside:withEvent:`方法判斷觸摸點(diǎn)是否在當(dāng)前視圖內(nèi)阻逮;
若返回NO
,則hitTest:withEvent
:返回nil
;
若返回YES
,則向當(dāng)前視圖的所有子視圖(subviews
)發(fā)送hitTest:withEvent:
消息,所有子視圖的遍歷順序是從最頂層視圖一直到到最底層視圖秩彤,即從subviews
數(shù)組的末尾向前遍歷叔扼,直到有子視圖返回非空對(duì)象或者全部子視圖遍歷完畢.
如圖:
-
A
是UIWindow
的根視圖,因此漫雷,UIWindwo
對(duì)象會(huì)首相對(duì)A
進(jìn)行hit-test
瓜富;
2、顯然用戶點(diǎn)擊的范圍是在A
的范圍內(nèi)降盹,因此与柑,pointInside:withEvent:
返回了YES
,這時(shí)會(huì)繼續(xù)檢查A
的子視圖蓄坏;
3价捧、這時(shí)候會(huì)有兩個(gè)分支,B
和C
:
點(diǎn)擊的范圍不再B
內(nèi)涡戳,因此B
分支的pointInside:withEvent:
返回NO
结蟋,對(duì)應(yīng)的hitTest:withEvent:
返回nil
;
點(diǎn)擊的范圍在C
內(nèi)渔彰,即C
的pointInside:withEvent:
返回YES嵌屎;
4、這時(shí)候有D
和E
兩個(gè)分支:
點(diǎn)擊的范圍不再D
內(nèi)恍涂,因此D
的pointInside:withEvent:
返回NO
宝惰,對(duì)應(yīng)的hitTest:withEvent:
返回nil
;
點(diǎn)擊的范圍在E
內(nèi)再沧,即E
的pointInside:withEvent:
返回YES尼夺,由于E沒有子視圖(也可以理解成對(duì)E的子視圖進(jìn)行hit-test
時(shí)返回了nil
),因此,E
的hitTest:withEvent:
會(huì)將E
返回汞斧,再往回回溯,就是C
的hitTest:withEvent:
返回E--->>A
的hitTest:withEvent:
返回E
什燕。
至此粘勒,本次點(diǎn)擊事件的第一響應(yīng)者就通過響應(yīng)者鏈的事件分發(fā)邏輯成功的找到了。
若第一次有子視圖返回非空對(duì)象屎即,則
hitTest:withEvent:
方法返回此對(duì)象庙睡,處理結(jié)束;
如所有子視圖都返回非技俐,則hitTest:withEvent:
方法返回自身(self
)载迄。
如果最終
hit-test
沒有找到第一響應(yīng)者妥畏,或者第一響應(yīng)者沒有處理該事件,則該事件會(huì)沿著響應(yīng)者鏈向上回溯,如果UIWindow
實(shí)例和UIApplication
實(shí)例都不能處理該事件湿酸,則該事件會(huì)被丟棄;
-
hitTest:withEvent:
方法將會(huì)忽略
1 .忽略隱藏(hidden=YES
)的視圖
禁止用戶操作(
userInteractionEnabled=YES
)的視圖alpha級(jí)別小于0.01(
alpha<0.01
)的視圖如果一個(gè)子視圖的區(qū)域超過父視圖的
bound
區(qū)域(父視圖的clipsToBounds
屬性為NO
闸翅,這樣超過父視圖bound
區(qū)域的子視圖內(nèi)容也會(huì)顯示).
那么正常情況下對(duì)子視圖在父視圖之外區(qū)域的觸摸操作不會(huì)被識(shí)別,因?yàn)楦敢晥D的
pointInside:withEvent:
方法會(huì)返回NO
,這樣就不會(huì)繼續(xù)向下遍歷子視圖了舟铜。當(dāng)然,也可以重寫pointInside:withEvent:
方法來處理這種情況仇穗。
Hit Testing 應(yīng)?用場(chǎng)景
- 事件穿透
- ?子視圖超出父視圖范圍
仿射變換數(shù)學(xué)原理講解
仿射變換 AffineTransform
流部,在iOS中的實(shí)現(xiàn)類是CGAffineTransform
和CATransform3D
,很多動(dòng)畫效果都需要用到仿射去完成纹坐,可以說仿射是動(dòng)畫基礎(chǔ).
原理是利用矩陣的相乘,得到變換后的坐標(biāo)系.
CGAffineTransform
-
CGAffineTransform
是一個(gè)可以和二維空間向量(例如CGPoint
)做乘法的3X2的矩陣
CGAffineTransformMakeRotation(CGFloat angle)
CGAffineTransformMakeScale(CGFloat sx, CGFloat sy)
CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty)
- 使用
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI_4);
self.layerView.layer.affineTransform = transform;
混合變換
Core Graphics
提供了一系列的函數(shù)可以在一個(gè)變換的基礎(chǔ)上做更深層次的變換枝冀,如果做一個(gè)既要縮放又要旋轉(zhuǎn)的變換.
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle)
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy)
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty)
當(dāng)操縱一個(gè)變換的時(shí)候,初始生成一個(gè)什么都不做的變換很重要--也就是創(chuàng)建一個(gè)CGAffineTransform
類型的空值耘子,矩陣論中稱作單位矩陣果漾,Core Graphics
同樣也提供了一個(gè)方便的常量:
CGAffineTransformIdentity
- 使用
CGAffineTransform transform = CGAffineTransformIdentity;
//scale by 50%
transform = CGAffineTransformScale(transform, 0.5, 0.5);
//rotate by 30 degrees
transform = CGAffineTransformRotate(transform, M_PI / 180.0 * 30.0);
//translate by 200 points
transform = CGAffineTransformTranslate(transform, 200, 0);
//apply transform to layer
self.layerView.layer.affineTransform = transform;
CATransform3D
CATransform3D也是一個(gè)矩陣,但是和2x3的矩陣不同谷誓,CATransform3D是一個(gè)可以在3維空間內(nèi)做變換的4x4的矩陣(圖5.6)跨晴。
蘋果提供的可變換的矩陣:
3D
的平移
和旋轉(zhuǎn)
多處了一個(gè)z參數(shù),并且旋轉(zhuǎn)函數(shù)除了angle
之外多出了x,y,z
三個(gè)參數(shù)片林,分別決定了每個(gè)坐標(biāo)軸方向上的旋轉(zhuǎn):
CATransform3DMakeRotation(CGFloat angle, CGFloat x, CGFloat y, CGFloat z)
CATransform3DMakeScale(CGFloat sx, CGFloat sy, CGFloat sz)
CATransform3DMakeTranslation(Gloat tx, CGFloat ty, CGFloat tz)