目錄(transform)
- 基礎(chǔ)及矩陣概念
- 2D仿射
- 3D仿射
1. 基礎(chǔ)及矩陣概念
- 在iOS的動(dòng)畫效果中,變換是很常見的栖秕,包括仿射變換和3D變換等放接。變換的終極原理就是矩陣的乘法運(yùn)算,3D變換涉及到三維透視投影的一些原理知識(shí)劲绪。
-
transform
基本概念
transform
在矩陣變換的層面上改變視圖的顯示效果燕少,完成旋轉(zhuǎn)卡者、形變、平移等等操作客们。在它被修改的同時(shí)崇决,視圖的frame
也會(huì)被真實(shí)改變。有兩個(gè)數(shù)據(jù)類型用來表示transform
底挫,分別是CGAffineTransform
和CATransform3D
恒傻。前者作用于UIView
,后者為layer
層次的變換類型建邓∮澹基于后者可以實(shí)現(xiàn)更加強(qiáng)大的功能。
UIView
可以通過設(shè)置transform
屬性做變換官边,但實(shí)際上它只是封裝了內(nèi)部圖層的變換沸手。
CALayer
同樣也有一個(gè)transform
屬性,但它的類型是CATransform3D
注簿,而不是CGAffineTransform
契吉。CALayer
對(duì)應(yīng)于UIView
的transform
屬性叫做affineTransform
诡渴, - 矩陣概念
矩陣 × 坐標(biāo):當(dāng)你用矩陣乘以一個(gè)坐標(biāo)時(shí)捐晶,它們的乘積就是一個(gè)變換后的新坐標(biāo)。
齊次坐標(biāo):為了把二維圖形的變化統(tǒng)一在一個(gè)坐標(biāo)系里妄辩,引入了齊次坐標(biāo)的概念惑灵,即把一個(gè)圖形用一個(gè)三維矩陣表示,其中第三列總是(0,0,1)
(為了能讓矩陣做乘法)眼耀,用來作為坐標(biāo)系的標(biāo)準(zhǔn)英支。所以所有的變化都由前兩列完成。
為了能讓矩陣做乘法:左邊矩陣的列數(shù)一定要和右邊矩陣的行數(shù)個(gè)數(shù)相同哮伟,所以要給矩陣填充一些標(biāo)志值潭辈,使得既可以讓矩陣做乘法,又不改變運(yùn)算結(jié)果澈吨,并且沒必要存儲(chǔ)這些添加的值,因?yàn)樗鼈兊闹挡粫?huì)發(fā)生變化寄摆,但是要用來做運(yùn)算谅辣。因此,通常會(huì)用3×3(而不是2×3)
的矩陣來做二維變換.
當(dāng)對(duì)圖層應(yīng)用變換矩陣婶恼,圖層矩形內(nèi)的每一個(gè)點(diǎn)都被相應(yīng)地做變換桑阶,從而形成一個(gè)新的四邊形的形狀柏副。CGAffineTransform
中的“仿射”的意思是無論變換矩陣用什么值,圖層中平行的兩條線在變換之后任然保持平行蚣录,CGAffineTransform
可以做出任意符合上述標(biāo)注的變換
單位矩陣
CGAffineTransformIdentity
-
仿射變換的原理和計(jì)算
仿射變化原理是數(shù)學(xué)中的矩陣原理(線性代數(shù)-矩陣分析)割择,要弄明白仿射矩陣對(duì)作用點(diǎn)的影響,還得先看看矩陣的乘法怎么計(jì)算萎河。基礎(chǔ)-矩陣的乘法
計(jì)算規(guī)則:- 不符合交換律(A和B是矩陣荔泳,AB不一定等于BA)
- 當(dāng)矩陣A的列數(shù)等于矩陣B的行數(shù)是,才可以計(jì)算
- 計(jì)算的結(jié)果矩陣C的行數(shù)等于A的行數(shù)虐杯,列數(shù)等于B的列數(shù)(如A是m×n矩陣和B是n×p矩陣玛歌,它們的乘積C是一個(gè)m×p矩陣 )
- 結(jié)果矩陣C的第 i 行第 j 列的元素Cij 等于矩陣A的第 i 行的元素與矩陣B的第 j 列對(duì)應(yīng)元素乘積之和
矩陣A =
[1 1]
[2 0]
矩陣B =
[0 2 3]
[1 1 2]
計(jì)算過程:
矩陣C = A * B =
[(1 * 0 + 1 * 1) (1 * 2 + 1 * 1) (1 * 3 + 1 * 2)]
[(2 * 0 + 0 * 1) (2 * 2 + 0 * 1) (2 * 3 + 0 * 2)]
矩陣C =
[1 3 5]
[0 4 6]
- 仿射變換的矩陣計(jì)算
仿射計(jì)算中,(以二維坐標(biāo)為例擎椰,坐標(biāo)點(diǎn)為x,y)我們?cè)O(shè)我們的坐標(biāo)點(diǎn)矩陣為
坐標(biāo)點(diǎn)矩陣
A = [x y 1]
仿射變換基礎(chǔ)矩陣為:
B =
[a b 0]
[c d 0]
[tx ty 1]
根據(jù)矩陣計(jì)算規(guī)則我們知道A x B的結(jié)果是一個(gè)1行3列的矩陣支子,設(shè)A x B得到的新矩陣C ,那么C的矩陣應(yīng)該為
C = [(a*x+c*y+tx) (b*x+d*y+ty) 1]
設(shè)C為 = [x' y' 1] , 那么可以得到
x' = a*x + c*y + tx
y' = b*x + d*y + ty
2. 2D仿射
- 仿射是什么
仿射變換可以理解為- 對(duì)坐標(biāo)進(jìn)行放縮达舒,旋轉(zhuǎn)值朋,平移后取得新坐標(biāo)的值。
- 經(jīng)過對(duì)坐標(biāo)軸的放縮巩搏,旋轉(zhuǎn)昨登,平移后原坐標(biāo)在在新坐標(biāo)領(lǐng)域中的值。
- transform是一個(gè)矩陣塔猾,變換后的點(diǎn)坐標(biāo)等于之前的點(diǎn)坐標(biāo)乘以矩陣
當(dāng)操縱一個(gè)變換的時(shí)候篙骡,初始生成一個(gè)什么都不做的變換很重要--也就是創(chuàng)建一個(gè)CGAffineTransform
類型的空值,矩陣論中稱作單位矩陣
丈甸,Core Graphics同樣也提供了一個(gè)方便的常量:CGAffineTransformIdentity
iOS封裝了幾個(gè)好用的CGAffineTrans的API去實(shí)現(xiàn)仿射變換的效果
注意:帶Make的糯俗,起點(diǎn)固定,每次控制的事件只針對(duì)起點(diǎn)睦擂。不帶Make的:為一個(gè)變換再加上平移得湘,針對(duì)上一個(gè)位置,不針對(duì)起點(diǎn)顿仇。
//位移仿射
CGAffineTransformMakeTranslation
CGAffineTransformTranslate
//旋轉(zhuǎn)仿射
CGAffineTransformMakeRotation
CGAffineTransformRotate
//縮放仿射
CGAffineTransformMakeScale
CGAffineTransformScale
//疊加仿射效果
CGAffineTransformConcat
//仿射矩陣方法淘正,可以直接做效果疊加
CGAffineTransformMake (sx,shx,shy,sy,tx,ty)
帶make的方法是直接返回一個(gè)仿射變換效果,不帶make方法是用來給已有的仿射效果疊加效果
類似于CGAffineTransformConcat方法的作用
CATransform3D也對(duì)應(yīng)一組相似的api臼闻,這個(gè)后面在研究到它的時(shí)候仔細(xì)說說.
在大多數(shù)情況下用這幾個(gè)封裝好的仿射方法基本就能實(shí)現(xiàn)大多數(shù)的需求鸿吆。但是既然是研究仿射,可以看CGAffineTransform最基礎(chǔ)的那個(gè)仿射方法的使用述呐,能理解這個(gè)方法的使用惩淳,基本上就知道仿射是個(gè)什么意思了。
CGAffineTransformMake(CGFloat a,CGFloat b,CGFloat c,CGFloat d,CGFloat tx,CGFloat ty)
這個(gè)方法的6個(gè)參數(shù)可以拼出一個(gè)矩陣
//仿射矩陣
[a b 0]
[c d 0]
[tx ty 1]
仿射變化的定義有點(diǎn)復(fù)雜乓搬,我自己理解就是: 點(diǎn)p(以二維坐標(biāo)為例)通過仿射矩陣C 后變成新的點(diǎn)p' 思犁。
以上面的縮放仿射變化CGAffineTransformScale為例代虾。就是view中每一個(gè)點(diǎn)p通過矩陣C后,view中的每一個(gè)新的點(diǎn)p'組成的新的圖形激蹲,相比之前的view有了縮放的效果棉磨。
這步很關(guān)鍵。根據(jù)這個(gè)公式学辱,那么仿射矩陣就可以分成5種分別對(duì)應(yīng):平移(Translation),縮放(Scale),翻轉(zhuǎn)(Flip),旋轉(zhuǎn)(Rotation),剪切(Shear)
平移演化
設(shè)a,d=1 c,b = 0 那么
x' = a*x + c*y + tx
y' = b*x + d*y + ty
就變成了
x' = x + tx
y' = y + ty
這個(gè)不就是新的點(diǎn)P'(x' y') 是根據(jù)原來的P在x和y分別添加了一個(gè)常量就可以得到了嘛乘瓤? 所以這個(gè)就是仿射中的平移效果了。把a(bǔ),b,c,d帶入仿射的基礎(chǔ)矩陣项郊,就得了仿射的位移矩陣
//仿射基礎(chǔ)矩陣
[a b 0]
[c d 0]
[tx ty 1]
//仿射位移矩陣
[1 0 0]
[0 1 0]
[tx ty 1]
再來看看代碼
向右移動(dòng)300的仿射效果
CGAffineTransform translate = CGAffineTransformMakeTranslation(300, 0)
使用仿射基礎(chǔ)方法
CGAffineTransform translate = CGAffineTransformMake(1,0,0,1,300,0)
縮放演化
x' = a*x + c*y + tx
y' = b*x + d*y + ty
設(shè) c,b,tx,ty = 0 ,得到
x' = a*x
y' = d*y
新坐標(biāo)(x',y')和原坐標(biāo)是倍數(shù)關(guān)系馅扣,這個(gè)就可以用來做縮放效果了。所以得到縮放矩陣
//仿射縮放矩陣
[a 0 0]
[0 d 0]
[0 0 1]
//也可以寫成
[sx 0 0]
[0 sy 0]
[0 0 1]
代碼
//x和y都放大1倍
CGAffineTransform scaleAffine = CGAffineTransformMakeScale(2, 2)
//使用仿射基礎(chǔ)方法
CGAffineTransform scaleAffine = CGAffineTransformMake(2,0,0,2,0,0)
剪切演化
x' = a*x + c*y + tx
y' = b*x + d*y + ty
設(shè) a,d = 1 tx,ty = 0 ,得到
x' = x + cy
y' = y + bx
x和y的變化總是相互關(guān)聯(lián)着降,這個(gè)就是剪切(Shear)
//仿射剪切矩陣
[1 b 0]
[c 1 0]
[0 0 1]
//也可以寫成
[1 shx 0]
[shy 1 0]
[0 0 1]
代碼
//使用仿射基礎(chǔ)方法CGAffineTransformMake,設(shè)置x和y都為0.5的斜切
CGAffineTransform shearAffine = CGAffineTransformMake(1,0.5,0.5,1,0,0)
剪切效果只能用CGAffineTransformMake實(shí)現(xiàn),但是通過CATransform3DMakeRotation可以有類似的效果
旋轉(zhuǎn)演化
//仿射旋轉(zhuǎn)矩陣
[cosa sina 0]
[-sina cosa 0]
[0 0 1]
代碼
CGAffineTransform rotation = CGAffineTransformMake(CGFloat( cos(M_PI_4) ), CGFloat( sin(M_PI_4) ), -CGFloat( sin(M_PI_4) ), CGFloat( cos(M_PI_4) ), 0, 0)
翻轉(zhuǎn)演化
我不知道使用CGAffineTransformMake()如何設(shè)置矩陣可以實(shí)現(xiàn)翻轉(zhuǎn)效果差油。我閱讀的所有Flip效果都是使用CATransform3D實(shí)現(xiàn)的,代碼如下
//Flip仿射任洞,要是有3D去實(shí)現(xiàn)
CATransform3D flip = CATransform3DMakeRotation(angle, x, y, z)
//示例
CATransform3D flipX = CATransform3DMakeRotation(CGFloat(M_PI), 1, 0, 0)
CATransform3D flipY = CATransform3DMakeRotation(CGFloat(M_PI), 0, 1, 0)
CATransform3D flipZ = CATransform3DMakeRotation(CGFloat(M_PI), 0, 0, 1)
總結(jié)一下CATransform3DMakeRotation方法的6個(gè)參數(shù)
在不考慮旋轉(zhuǎn)時(shí)蓄喇,CATransform3DMakeRotation6個(gè)參數(shù)可以寫成
//sx,sy:縮放因子
//shx,shy:斜切因子
//tx,ty:移動(dòng)因子
CGAffineTransformMake (sx,shx,shy,sy,tx,ty)
這個(gè)是一個(gè)初始化矩陣,帶入矩陣算法計(jì)算后的結(jié)構(gòu)會(huì)得到
x'=x , y'=y
它的作用是清除之前對(duì)矩陣設(shè)置的仿射效果交掏,或者用來初始化一個(gè)原始無效果的仿射矩陣
矩陣初始值妆偏。[ 1 0 0 1 0 0 ]
[ 1 0 0 ]
[ 0 1 0 ]
[ 0 0 1 ]
方法:
//用來連接兩個(gè)變換效果并返回。返回的t = t1 * t2
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2)
//矩陣初始值盅弛。[ 1 0 0 1 0 0 ]
CGAffineTransformIdentity
//檢查是否有做過仿射效果
CGAffineTransformIsIdentity(transform)
//檢查2個(gè)仿射效果是否相同
CGAffineTransformEqualToTransform(transform1,transform2)
//仿射效果反轉(zhuǎn)(反效果钱骂,比如原來擴(kuò)大,就變成縮信才簟)
CGAffineTransformInvert(transform)
- 應(yīng)用
放射矩陣一個(gè)常用的情形就是根據(jù)用戶的手勢(shì)來相應(yīng)的改變視圖的變換
UIPanGestureRecognizer
對(duì)應(yīng)位移
UIPinchGestureRecognizer
對(duì)應(yīng)縮放
UIRotationGestureRecognizer
對(duì)應(yīng)旋轉(zhuǎn)
通常如果需要看到實(shí)時(shí)的手指移動(dòng)視圖就相應(yīng)的變換的技巧就是见秽,每次接收到對(duì)應(yīng)的gesture
時(shí)間就相應(yīng)的改變view的transform
,然后吧這個(gè)gesture
對(duì)應(yīng)的translation
讨盒、scale
解取、rotation
置為初始值。
3. 3D仿射
- 三維坐標(biāo)系:視角垂直與屏幕而言返顺,x軸向右禀苦,y軸向下,z軸垂直屏幕向外遂鹊。和
UIView
嚴(yán)格的二維坐標(biāo)系不同振乏,CALayer存在于一個(gè)三維空間當(dāng)中。CALayer
還有另外兩個(gè)屬性秉扑,zPosition
和anchorPoint
最實(shí)用的功能就是改變圖層的顯示順序昆码。
self.greenView.layer.zPosition=1.0f;
- 錨點(diǎn) anchorPoint
圖層的錨點(diǎn)anchorPoint:是一個(gè)CGPoint值,x,y取值范圍(0~1)赋咽,默認(rèn)為(0.5,0.5) 對(duì)于圖層本身而言吨娜,顧名思義脓匿,錨點(diǎn)就用來定位圖層的點(diǎn)。錨點(diǎn)有兩個(gè)職能:
(1)與position一同確定圖層相對(duì)于父圖層的位置宦赠;
(2)通過設(shè)置該屬性來實(shí)現(xiàn)視圖圍繞不同位置旋轉(zhuǎn)陪毡。記得在視圖添加到父視圖之后在進(jìn)行設(shè)置,因?yàn)閒rame也是相對(duì)于錨點(diǎn)的勾扭。
作為圖層旋轉(zhuǎn)毡琉、平移、縮放的中心
self.menuViewController.view.layer.anchorPoint = CGPointMake(1.0,0);
當(dāng)圖層發(fā)生變換時(shí)妙色,這個(gè)點(diǎn)永遠(yuǎn)位于圖層變換之前anchorPoint的位置桅滋。當(dāng)改變一個(gè)圖層的position,你也改變了它的錨點(diǎn)身辨,做3D變換的時(shí)候要時(shí)刻記住這一點(diǎn)丐谋,當(dāng)你視圖通過調(diào)整m34來讓它更加有3D效果,應(yīng)該首先把它放置于屏幕中央煌珊,然后通過平移來把它移動(dòng)到指定位置(而不是直接改變它的position)号俐,這樣所有的3D圖層都共享一個(gè)錨點(diǎn)。
- 關(guān)于錨點(diǎn)(anchorPoint)與position
- position是決定了layer顯示在父控件的哪個(gè)位置,默認(rèn)position是該layer的中心點(diǎn).
- anchorPoint決定了layer自身顯示在position的哪個(gè)位置.
- position與錨點(diǎn)的默認(rèn)點(diǎn)為中心點(diǎn)
- position總是與錨點(diǎn)顯示在同一位置
- layer是否發(fā)生偏移有錨點(diǎn)決定
- 3D仿射矩陣
3D仿射矩陣類似于2D仿射定庵,3D仿射也有一個(gè)基礎(chǔ)矩陣吏饿,并且比2D的多一個(gè)維度
CGAffineTransform transform = CGAffineTransformIdentity;
結(jié)果:(CGAffineTransform) transform = (a = 1, b = 0, c = 0, d = 1, tx = 0, ty = 0)
[m11 m12 m13 m14]
[m21 m22 m23 m24]
[m31 m32 m33 m34]
[m41 m42 m43 m44]
矩陣的計(jì)算過程和2D類似,最后也能得到矩陣中每個(gè)位置的值對(duì)3D仿射效果的作用蔬浙。我直接把結(jié)果貼出來猪落。
平移因子: m41(x位置) m42(y位置) m43(z位置)
縮放因子: m11(x位置) m22(y位置)
切變因子: m21(x位置) m12(y位置)
旋轉(zhuǎn)因子: m13(x位置) m31(y位置)
透視因子: m34(有旋轉(zhuǎn)才能看出效果)
m34的默認(rèn)值是0,我們可以通過設(shè)置m34為(-1.0 / d)來應(yīng)用透視效果敛滋,d代表了視角相機(jī)和屏幕之間的距離许布,以像素為單位,那應(yīng)該如何計(jì)算這個(gè)距離呢绎晃?大概估算一個(gè)就行了蜜唾。
因?yàn)橐暯窍鄼C(jī)實(shí)際上并不存在,所以可以根據(jù)屏幕上的顯示效果自由決定它放置的位置庶艾。通常500-1000就已經(jīng)很好了袁余,但對(duì)于特定的圖層有時(shí)候更小后者更大的值會(huì)看起來更舒服,減少距離的值會(huì)增強(qiáng)透視效果咱揍,所以一個(gè)非常微小的值會(huì)讓它看起來更加失真颖榜,然而一個(gè)非常大的值會(huì)讓它基本失去透視效果
3D仿射常用的方法
//位移3D仿射
CATransform3DMakeTranslation
CATransform3DTranslation
//旋轉(zhuǎn)3D仿射:x-y-z軸的有個(gè)確定的范圍(介于-1 和+1之間)
CATransform3DMakeRotation
CATransform3DRotation
angle 是所需要變化的角度
x y z 設(shè)置為零表示不圍繞該軸做旋轉(zhuǎn),如果設(shè)置為1,則繞該軸做旋轉(zhuǎn)掩完。
//縮放3D仿射
CATransform3DMakeScale
CATransform3DScale
//疊加3D仿射效果
CATransform3DConcat
//仿射基礎(chǔ)3D方法噪漾,可以直接做效果疊加
CGAffineTransformMake (sx,shx,shy,sy,tx,ty)
矩陣初始值:[ 1 0 0 0 1 0 0 0 1 0 0 0]
這個(gè)是一個(gè)初始化矩陣,帶入矩陣算法計(jì)算后的結(jié)構(gòu)會(huì)得到
x'=x , y'=y , z'=z
它的作用是清除之前對(duì)矩陣設(shè)置的仿射效果且蓬,或者用來初始化一個(gè)原始無效果的仿射矩陣
矩陣初始值:
[ 1 0 0 0 ]
[ 0 1 0 0 ]
[ 0 0 1 0 ]
[ 0 0 0 1 ]
//矩陣初始值欣硼。[ 1 0 0 0 1 0 0 0 1 0 0 0]
CATransform3DIdentity
//檢查是否有做過仿射3D效果
CATransform3DIsIdentity(transform)
//檢查是否是一個(gè)仿射3D效果
CATransform3DIsAffine(transform)
//檢查2個(gè)3D仿射效果是否相同
CATransform3DEqualToTransform(transform1,transform2)
//3D仿射效果反轉(zhuǎn)(反效果,比如原來擴(kuò)大恶阴,就變成縮姓┦ぁ)
CATransform3DInvert(transform)
//2D仿射轉(zhuǎn)換3D仿射
CATransform3DGetAffineTransform(transform)
CATransform3DMakeAffineTransform(transform)
CATransform3D與CGAffineTransform的轉(zhuǎn)換
//將一個(gè)CGAffinrTransform轉(zhuǎn)化為CATransform3DCATransform3D
CATransform3DMakeAffineTransform (CGAffineTransform m);
//判斷一個(gè)CATransform3D是否可以轉(zhuǎn)換為CAAffineTransformbool
CATransform3DIsAffine (CATransform3D t);
//將CATransform3D轉(zhuǎn)換為CGAffineTransformCGAffineTransform
CATransform3DGetAffineTransform (CATransform3D t);
當(dāng)我們改變過一個(gè)view.transform
屬性或者view.layer.transform
的時(shí)候需要恢復(fù)默認(rèn)狀態(tài)的話,記得先把他 們重置為:
view.transform = CGAffineTransformIdentity;
view.layer.transform = CATransform3DIdentity;
CALayer
的transform
屬性是是個(gè)CATransform3D
類型的數(shù)據(jù),默認(rèn)值為CATransform3DIdentity
冯事。需要注意的是,CALayer
是有隱式動(dòng)畫的,如果你想關(guān)掉隱式動(dòng)畫,用
[CATransaction setDisableActions:YES];
另外,要特地說明一下矩陣中的一個(gè)參數(shù)m34,m34影響透視效果.當(dāng)然,z方向上得有變化才會(huì)有透視效果,數(shù)值越大,透視效果越明顯.正值/負(fù)值都有意義,導(dǎo)致透視方向的不同焦匈。d越大,效果越不明顯昵仅,d越小缓熟,效果越明顯甚至導(dǎo)致失真。d的一個(gè)推薦的值是500-1000之間岩饼。
- 透視效果
#define RADIANS_TO_DEGREES(x) ((x)/M_PI*180.0)
CATransform3D transform = CATransform3DIdentity;
// 透視效果
transform.m34 = 0.0005;
transform = CATransform3DRotate(transform,(M_PI/180*40), 0, 1, 0);
[layer setTransform:transform];
注意我們使用的旋轉(zhuǎn)常量是`M_PI_4`荚虚,而不是你想象的`45`,因?yàn)閕OS的變換函數(shù)使用弧度而不是角度作為單位籍茧。
弧度用數(shù)學(xué)常量`pi`的倍數(shù)表示版述,一個(gè)`pi`代表`180`度,所以四分之一的`pi`就是`45`度寞冯。
第二行一定要寫在第三行的前面渴析;m34:透視效果m34= -1/M,M越小吮龄,透視效果越明顯俭茧,必須在有旋轉(zhuǎn)效果的前提下,才會(huì)看到透視效果漓帚。
- 合并兩個(gè)CATransform3D(CATransform3DConcat)
CATransform3D CATransform3DConcat ( CATransform3D a, CATransform3D b );
- CATransform3DInvert效果反轉(zhuǎn)(反效果母债,比如原來擴(kuò)大,就變成縮谐⒍丁)
CATransform3D CATransform3DInvert ( CATransform3D t );
- CATransform3D與CGAffineTransform的轉(zhuǎn)換
//將一個(gè)CGAffinrTransform轉(zhuǎn)化為CATransform3DCATransform3D
CATransform3DMakeAffineTransform (CGAffineTransform m);
//判斷一個(gè)CATransform3D是否可以轉(zhuǎn)換為CAAffineTransformbool
CATransform3DIsAffine (CATransform3D t);
//將CATransform3D轉(zhuǎn)換為CGAffineTransformCGAffineTransform
CATransform3DGetAffineTransform (CATransform3D t);
- 減輕鋸齒-
shouldRasterize
屬性的默認(rèn)值是NO
毡们,可將其設(shè)置為YES
來減輕鋸齒的效果。記得動(dòng)畫結(jié)束時(shí)將其設(shè)置為NO
昧辽。
self.menuViewController.view.layer.shouldRasterize = NO;
- content
設(shè)置CALayer
的contents
屬性為一個(gè)image
來設(shè)置圖片衙熔,設(shè)置contentGravity
來指定圖層內(nèi)容的拉伸方式。
iOS CATransform3D
搅荞,旋轉(zhuǎn)之后出現(xiàn)的鋸齒處理方法
layer.shouldRasterize = YES;