iOS開發(fā)經(jīng)驗(yàn)(6)-Transform

目錄(transform)

  1. 基礎(chǔ)及矩陣概念
  2. 2D仿射
  3. 3D仿射
1. 基礎(chǔ)及矩陣概念
仿射變換.png
  • 在iOS的動(dòng)畫效果中,變換是很常見的栖秕,包括仿射變換和3D變換等放接。變換的終極原理就是矩陣的乘法運(yùn)算,3D變換涉及到三維透視投影的一些原理知識(shí)劲绪。
  • transform基本概念
    transform在矩陣變換的層面上改變視圖的顯示效果燕少,完成旋轉(zhuǎn)卡者、形變、平移等等操作客们。在它被修改的同時(shí)崇决,視圖的frame也會(huì)被真實(shí)改變。有兩個(gè)數(shù)據(jù)類型用來表示transform底挫,分別是CGAffineTransformCATransform3D恒傻。前者作用于UIView,后者為layer層次的變換類型建邓∮澹基于后者可以實(shí)現(xiàn)更加強(qiáng)大的功能。
    UIView可以通過設(shè)置transform屬性做變換官边,但實(shí)際上它只是封裝了內(nèi)部圖層的變換沸手。
    CALayer同樣也有一個(gè)transform屬性,但它的類型是CATransform3D注簿,而不是CGAffineTransform契吉。CALayer對(duì)應(yīng)于UIViewtransform屬性叫做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è)屬性秉扑,zPositionanchorPoint
    最實(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;

CALayertransform屬性是是個(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è)置CALayercontents屬性為一個(gè)image來設(shè)置圖片衙熔,設(shè)置contentGravity來指定圖層內(nèi)容的拉伸方式。
    iOS CATransform3D 搅荞,旋轉(zhuǎn)之后出現(xiàn)的鋸齒處理方法
layer.shouldRasterize = YES;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末红氯,一起剝皮案震驚了整個(gè)濱河市框咙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌痢甘,老刑警劉巖喇嘱,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異塞栅,居然都是意外死亡婉称,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門构蹬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悔据,你說我怎么就攤上這事庄敛。” “怎么了科汗?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵藻烤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我头滔,道長(zhǎng)怖亭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任坤检,我火速辦了婚禮兴猩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘早歇。我一直安慰自己倾芝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布箭跳。 她就那樣靜靜地躺著晨另,像睡著了一般。 火紅的嫁衣襯著肌膚如雪谱姓。 梳的紋絲不亂的頭發(fā)上借尿,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音屉来,去河邊找鬼路翻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛奶躯,可吹牛的內(nèi)容都是我干的帚桩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼嘹黔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼账嚎!你這毒婦竟也來了莫瞬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤郭蕉,失蹤者是張志新(化名)和其女友劉穎疼邀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體召锈,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡旁振,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了涨岁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拐袜。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖梢薪,靈堂內(nèi)的尸體忽然破棺而出蹬铺,到底是詐尸還是另有隱情,我是刑警寧澤秉撇,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布甜攀,位于F島的核電站,受9級(jí)特大地震影響琐馆,放射性物質(zhì)發(fā)生泄漏规阀。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一瘦麸、第九天 我趴在偏房一處隱蔽的房頂上張望谁撼。 院中可真熱鬧,春花似錦瞎暑、人聲如沸彤敛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)墨榄。三九已至,卻和暖如春勿她,著一層夾襖步出監(jiān)牢的瞬間袄秩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工逢并, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留之剧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓砍聊,卻偏偏與公主長(zhǎng)得像背稼,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子玻蝌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

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