最近看了一下關(guān)于圖層和動畫的內(nèi)容耿导,所以寫了一份總結(jié)声怔,算是對這些內(nèi)容的匯總吧,都是一些簡單的基礎(chǔ)知識碎节,不知道大家都了不了解捧搞。
除了和用戶的交互之外,圖層的很多屬性和視圖基本上都是一樣的,今天就先從CALayer的一些基礎(chǔ)的屬性入手胎撇,沒有套路和技巧介粘,只是對屬性的介紹:
一、contents
contents是CALayer的一個屬性:@property(nullable, strong) id contents;
它的類型是id
晚树,使用contents我們可以為一個普通的圖層添加一張圖片姻采,但是在賦值的時候,只有CGImageRef
類型才有效爵憎,并且需要使用bridged
關(guān)鍵字進行轉(zhuǎn)換慨亲,因為CGImageRef并不是一個Cocoa對象,而是一個Core Foundation類型宝鼓,所有正確的賦值方式為:
UIImage *image = [UIImage imageNamed:@"image_1.jpg"];
self.layerView.layer.contents = (__bridge id)image.CGImage;
效果和使用UIImageView時一樣一樣的:
和contents相關(guān)的還有以下幾個屬性:
contentsGravity刑棵、contentsScale、contentsRect愚铡、contentsCenter
contentsGravity
contentsGravity
和UIView的contentMode
屬性的作用是相似的蛉签,我們可以看到上面的效果圖中的圖片被拉伸了,我們平時在使用UIImageView展示圖片的時候也會出現(xiàn)這種情況沥寥,我們設(shè)置contentMode
屬性就可以解決碍舍,在圖層中,我們使用contentsGravity
屬性就可以了邑雅。
contentsGravity
有以下這些可選的值:
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
kCAGravityResize
kCAGravityResizeAspect
kCAGravityResizeAspectFill
值得注意的是:這些值并不是枚舉片橡,他們都是常量字符串。
為我們上面的代碼再添加一句:
self.layerView.layer.contentsGravity = kCAGravityResizeAspect;
我們可以發(fā)現(xiàn)淮野,圖片就正常了捧书,效果如下:
contentsScale
contentsScale
屬性定義了contents中圖片的的像素尺寸和視圖大小的比例,它用來判斷在繪制圖層的時候應(yīng)該為contents創(chuàng)建的空間大小录煤,和需要顯示的圖片的拉伸度鳄厌。如果contentsScale設(shè)置為1.0,將會以每個點1個像素繪制圖片妈踊,如果設(shè)置為2.0了嚎,則會以每個點2個像素繪制圖片,這就是Retina屏幕了廊营。
如果我們已經(jīng)使用contentsGravity
屬性使圖片拉伸了歪泳,那么我們再設(shè)置contentsScale
就會失效(不是所有的contentsGravity的值都會拉伸圖片)。
我們先將設(shè)置contentsGravity
的代碼改為:
self.layerView.layer.contentsGravity = kCAGravityCenter;
然后添加:
self.layerView.layer.contentsScale = image.scale;
我們發(fā)現(xiàn)顯示的圖片跟圖片本身大小一致:
我這里使用的是1倍圖露筒,如果我們?yōu)閳D片的名字后面添加一個@2x呐伞,然后就變成這樣了:
原因就不用我多說了吧。
contentsRect
contentsRect
屬性規(guī)定了我們在contents中可以顯示的圖片的區(qū)域慎式,這個理解起來也很容易伶氢,但是要注意的是:contentsRect
不是一個絕對值(點或者像素)趟径,而是一個相對值,以左上角為坐標原點癣防,單位坐標在0~1之間蜗巧,當然也可以是負數(shù)。設(shè)置了contentsRect
屬性只顯示左上角1/4區(qū)域:
self.layerView.layer.contentsRect = CGRectMake(0, 0, 0.5, 0.5);
效果圖如下:
contentsCenter
我們在日常的開發(fā)中蕾盯,有時候UI給的圖片我們在顯示的時候需要對圖片進行拉伸幕屹,但是又想只拉伸中間的部分,四周的一些區(qū)域不拉伸级遭,我們會使用-resizableImageWithCapInsets:
方法設(shè)置一下四周不被拉伸的區(qū)域望拖,contentsCenter
屬性在圖層中起到的也是這個作用,contentsCenter
的默認值是{0, 0, 1, 1}挫鸽,也就是整張圖片都被拉伸说敏,如果將值改為{0.25,0.25丢郊,0.5像云,0.5}就表示x,y都從左上角1/4處開始蚂夕,寬和高分別為圖片尺寸的一半大小,所圍成的區(qū)域被拉伸腋逆,其他區(qū)域不拉伸婿牍。由于我找的圖片素材效果不太明顯,所有就不貼效果圖了惩歉。
二等脂、幾何屬性
在圖層的幾個幾何屬性中爆价,我們重點介紹anchorPoint
跪但。
不過在此之前也簡單說一下frame
删铃、bounds
危尿、position
处嫌,一句話總結(jié):frame
代表了圖層的外部坐標(相對于父圖層)嘉冒,bounds是內(nèi)部坐標(相對于自身)蛙奖,position代表了相對于父圖層anchorPoint所在的位置惫撰。改變圖層的bounds
亮垫、bounds
和transform
模软,都會令frame
發(fā)生改變。
比如饮潦,我們將圖層旋轉(zhuǎn)45度燃异,然后看一下旋轉(zhuǎn)前后圖層的frame:
NSLog(@"x:%f,y:%f",self.layerView.layer.frame.origin.x,self.layerView.layer.frame.origin.y);
self.layerView.layer.affineTransform = CGAffineTransformMakeRotation(M_PI_4);
NSLog(@"x:%f,y:%f",self.layerView.layer.frame.origin.x,self.layerView.layer.frame.origin.y);
x:112.500000,y:233.500000
x:63.756313,y:209.756313
anchorPoint
上面說到,position代表了相對于父圖層anchorPoint所在的位置继蜡,通過改變anchorPoint回俐,圖層的frame也會發(fā)生改變逛腿。要理解anchorPoint很容易,直接上代碼就很直觀了:
創(chuàng)建兩個位置和大小都相同的layer仅颇,layer1為參照圖層单默,此時兩個圖層是重合的,
CALayer *layer1 = [[CALayer alloc]init];
layer1.frame = CGRectMake(100, 200, 150, 100);
layer1.backgroundColor = [UIColor redColor].CGColor;
[self.view.layer addSublayer:layer1];
CALayer *layer2 = [[CALayer alloc]init];
layer2.frame = CGRectMake(100, 200, 150, 100);
layer2.backgroundColor = [UIColor greenColor].CGColor;
[self.view.layer addSublayer:layer2];
NSLog(@"frame:{%.0f,%.0f,%.0f,%.0f}",layer2.frame.origin.x,layer2.frame.origin.y,layer2.frame.size.width,layer2.frame.size.height);
NSLog(@"bounds:{%.0f,%.0f,%.0f,%.0f}",layer2.bounds.origin.x,layer2.bounds.origin.y,layer2.bounds.size.width,layer2.bounds.size.height);
NSLog(@"positon:{%.0f,%.0f}",layer2.position.x,layer2.position.y);
NSLog(@"anchorPoint:{%.0f,%.0f}",layer2.anchorPoint.x,layer2.anchorPoint.y);
改變layer2的anchorPoint為{0灵莲,0}:
layer2.anchorPoint = CGPointMake(0, 0);
anchorPoint是在做圖層變換和動畫的時候雕凹,非常重要的一個屬性,它是圖層變換的一個把柄政冻,比如圖層在做旋轉(zhuǎn)的時候枚抵,就是以anchorPoint為基點旋轉(zhuǎn)的。實際上明场,在UIView中也有anchorPoint汽摹,只不過,系統(tǒng)并沒有暴露這個屬性苦锨,UIView的center屬性和圖層的position屬性是同一個概念逼泣,anchorPoint默認是{0.5,0.5}舟舒,所以UIView得center就是中心點了拉庶。
zPosition
CALaye
r存在于一個三維空間當中,它還有一個用來表示圖層在Z軸方向上位置的屬性zPosition
秃励,默認為0氏仗,如果改變這個屬性,就會改變多個圖層之間的顯示順序夺鲜。就用上面的例子演示一下皆尔,改變紅色圖層的zPosition
,圖層是一個非常非常薄的東西币励,所以我們只需要為zPosition
設(shè)置一個比較小的值就可以了慷蠕,比如說:1.0:
layer1.zPosition = 1.0f;
這樣,兩個圖層的順序就發(fā)生了改變食呻,不過需要注意的是:這只是用戶視角上看起來兩個圖層的順序改變了流炕,實際上兩個圖層在父圖層上還是原來的順序。
關(guān)于設(shè)置圖層效果的屬性仅胞,相信大家其實再熟悉不過了:
比如:圓角(conrnerRadius
)浪感、邊框(borderWidth
、borderColor
)饼问、陰影(shadowColor
影兽、shadowOffset
、shadowRadius
莱革、shadowOpacity
)峻堰、
圖層蒙版(mask
)讹开,在這里,就不啰嗦了捐名,還需要節(jié)省時間旦万,在接下來的文章中去總結(jié)更多更豐富的關(guān)于圖層的內(nèi)容。