圖層幾何學(xué)
視圖和圖層布局差異
- 視圖上的
center,在圖層上對應(yīng)叫position -
center和position都代表了當(dāng)前圖層相對于父圖層anchorPoint的位置 - 視圖改變
frame的實質(zhì)是改變圖層的frame -
frame是根據(jù)bounds,position和transform計算而來,所以當(dāng)其中任何一個值發(fā)生改變,他都會變化。相反,改變frame的值同樣會影響到他們當(dāng)中的值 -
frame的寬高可能和bounds不一致,比如視圖旋轉(zhuǎn)后
anchorPoint屬性 - 錨點
- 錨點可以理解為視圖的把柄,縮放移動旋轉(zhuǎn)等操作,會相對于錨點進行
-
anchorPoint通過單位坐標(biāo)描述,默認值是{0.5, 0.5}(圖層中心) -
anchorPoint發(fā)生了改變但是position沒有改變,所以圖層會重新布局,frame會發(fā)生改變 -
anchorPoint改變后,建議重新設(shè)置frame或position
坐標(biāo)系操作
- CALayer提供了點或矩形在不同圖層坐標(biāo)系間轉(zhuǎn)化的方法
- (CGPoint)convertPoint:(CGPoint)point fromLayer:(CALayer *)layer;
- (CGPoint)convertPoint:(CGPoint)point toLayer:(CALayer *)layer;
- (CGRect)convertRect:(CGRect)rect fromLayer:(CALayer *)layer;
- (CGRect)convertRect:(CGRect)rect toLayer:(CALayer *)layer;
- 可以通過設(shè)置
geometryFlipped翻轉(zhuǎn)整個坐標(biāo)系,他是BOOL型的
圖層的三維坐標(biāo)
- 圖層有
zPosition和anchorPointZ來描述在Z軸上的位置 - 圖層是一個完全扁平的對象,并沒有更多屬性來描述他在Z軸上的高度了
- 圖層的
zPosition除了使用CATransform3D來渲染3D動畫,還可以用來調(diào)整圖層的顯示順序,通常圖層的顯示順序,是使用“畫家的算法”不斷覆蓋上去的,但通過改變zPosition可以將圖層順序前置
圖層HitTest
- CALayer并不關(guān)心任何響應(yīng)事件但是它有一系列的方法幫你處理事件:
-containsPoint:和-hitTest: -
-containsPoint:接受一個在本圖層坐標(biāo)系下的CGPoint,如果這個點在圖層frame范圍內(nèi)就返回YES -
-hitTest:方法同樣接受一個CGPoint類型參數(shù),但返回的不是BOOL類型,它返回圖層本身,或者包含這個坐標(biāo)點的葉子節(jié)點圖層 -
-hitTest:的測算的順序依賴于圖層樹的順序,和zPosition改變后顯示順序無關(guān)。所以使用zPosition改變圖層顯示順序后,事件可能無法響應(yīng)
視覺效果
圓角
-
conrnerRadius屬性控制著圖層角的曲率 - 書中原話是這個曲率值只影響背景顏色而不影響背景圖片或是子圖層
-
masksToBounds設(shè)置成YES的話,子圖層超出父圖層的區(qū)域會被裁剪
圖層邊框
-
borderWidth描述了圖層邊框?qū)挾?,這個邊框的繪制是沿裁剪后的圖層邊緣,并且繪制在圖層邊界里面的,而且在所有子內(nèi)容之前,也在子圖層之前 -
borderColor描述了邊框顏色信息
陰影
- 若需要增加陰影表現(xiàn),只需要更改
shadowOpacity屬性,他是一個0.0(不可見)和1.0(完全不透明)之間的浮點數(shù) - 若要改動陰影的表現(xiàn),你可以使用CALayer的另外三個屬性:
shadowColor,shadowOffset和shadowRadius -
shadowRadius控制了陰影的模糊度,當(dāng)它的值是0的時候,陰影就和視圖一樣有一個非常確定的邊界線。當(dāng)值越來越大的時候,邊界線看上去就會越來越模糊和自然。蘋果的設(shè)計,更傾向于自然陰影,即值為0 - 陰影路徑是根據(jù)寄宿圖輪廓來確定的
- 陰影繪制在圖層外部,所以
masksToBounds設(shè)置成YES的話,陰影會被裁剪 - 如果想沿著內(nèi)容裁切,又想保留陰影,需要用到兩個圖層:一個只畫陰影的空的外圖層,和一個用masksToBounds裁剪內(nèi)容的內(nèi)圖層
- 如果在圖層渲染前知道陰影形狀會是什么樣子的,可以指定一個
shadowPath來提高性能
圖層蒙版
- 通常創(chuàng)建一個無矩形視圖最方便的方法,可以給它指定一個透明蒙板來實現(xiàn),使用
mask屬性,這個屬性所指向的類型就是CALayer -
mask圖層的color屬性是無關(guān)緊要的,真正重要的是圖層的輪廓。mask屬性就像是一個餅干切割機,mask圖層實心的部分會被保留下來,其他的則會被拋棄
拉伸過濾
-
當(dāng)圖片需要顯示不同的大小的時候,有一種叫做拉伸過濾的算法就起到作用了。它作用于原圖的像素上并根據(jù)需要生成新的像素顯示在屏幕上
我的理解例如需要將一張20x20圖顯示在40x40的圖層上,為了避免圖片的像素化,通過過濾算法生成新的像素圖
minificationFilter和magnificationFilter屬性描述了在圖片需要縮小或拉伸時所用的過濾器算法-
CALayer對圖片的拉伸提供了三種算法
- kCAFilterLinear - 默認過濾器
- kCAFilterNearest - 效率非???,但會使得壓縮圖片更糟,圖片放大之后也顯得塊狀或是馬賽克嚴重
- kCAFilterTrilinear - 提高了性能,也避免了小概率因舍入錯誤引起的取樣失靈的問題
-
如果是對于比較小的圖或者是差異特別明顯,極少斜線的大圖,那么kCAFilterNearest既保證效率,同時又會保留最好的呈現(xiàn)效果
kCAFilterLinear和kCAFilterTrilinear的差異并不明顯,如果是簡單圖,kCAFilterNearest將會是最優(yōu)選擇
組透明
UIView的
alpha屬性和CALayer的opacity屬性,這兩個屬性都是影響子層級的透明度的理想狀況下,當(dāng)設(shè)置了一個圖層的透明度,希望它包含的整個圖層樹像一個整體一樣的透明效果,但實際情況,有可能因為透明度的混合疊加造成的
為了避免透明度混合造成的視覺上的混亂,可以使用
shouldRasterize屬性,來實現(xiàn)組透明的效果。如果設(shè)置了這個屬性,在應(yīng)用透明度之前,圖層及其子圖層都會被整合成一個整體的圖片-
如果使用了shouldRasterize屬性,就要確保你設(shè)置了
rasterizationScale屬性去匹配屏幕,以防止出現(xiàn)Retina屏幕像素化的問題btn.layer.shouldRasterize = YES; btn.layer.rasterizationScale = [UIScreen mainScreen].scale;