CoreAnimation 寄宿圖

CoreAnimation 寄宿圖


    CoreAnimation 目錄html

    博客園makedown支持不佳,若有須要請進GitHub.git

寄宿圖:圖層中所包含的圖 by:旭寶愛吃魚github

    針對於寄宿圖我在這裏只討論contents屬性以及Custom Drawing.緩存

contents

content:內容app

    CALayer的contents屬性是一個id類型.iview

@property(nullable, strong) id contents;

    所以,能夠將任何類型的對象賦值給contents,可是若是將非CGImage類型的對象賦值給contents將會的到一個空白頁.contents之因此會存在這種現象是由於Mac OS的歷史緣由形成的.
    緣由: contents對CGImage類型的對象以及NSImage類型的對象都起做用!
    然而問題並非只有這麼一點點,咱們能夠嘗試將UIImage的CGImage賦值給contents,不幸的是將會獲得一個編譯報錯,產生錯誤的緣由是CGImage返回的CGImageRef並非一個Cocoa對象而是CoreFoundation類型,這時咱們須要用bridged關鍵字進行轉換(MRC下不須要).佈局

layer.contents = (__bridge id)image.CGImage;

    下面咱們把一張圖片賦值給contents.ui

    爲了便於對比我將原圖粘貼於此代理

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIImage * layerImage = [UIImage imageNamed:@"goddess"];
    
    // 在圖層上添加圖片
    self.customView.layer.contents = (__bridge id)layerImage.CGImage;// 圖片一 
}

    展現效果以下:
code

    經過兩行代碼咱們將GODDESS添加到圖層之上,可是與原圖相比咱們發現goddess變胖了許多,咱們不但願見到這中效果,所以咱們須要對contentGravity屬性進行設置.

contentGravity

contentGravity:圖層的展現類型.

    CALayer的contentsGravity屬性是一個NSString類型.

@property(copy) NSString *contentsGravity;

    contentsGravity並無採起枚舉類型的賦值方式,所以我在這裏列出其相應的賦值範圍.

  • kCAGravityCenter
  • kCAGravityTop
  • kCAGravityBottom
  • kCAGravityLeft
  • kCAGravityRight
  • kCAGravityTopLeft
  • kCAGravityTopRight
  • kCAGravityBottomLeft
  • kCAGravityBottomRight
  • kCAGravityResize
  • kCAGravityResizeAspect
  • kCAGravityResizeAspectFill

    爲了改變上面結果的缺陷咱們添加如下代碼:

layer.contentsGravity = kCAGravityResizeAspect;

    獲得如下效果:

contentsScale

contentsScale:像素尺寸與試圖大小的比例(默認1.0).

    contentsScale屬性是爲了適配高分辨的屏幕機制,若是咱們將其設置爲1.0咱們的獲得的即是一個點由兩個像素組成,若是將其設置爲2.0咱們獲得的即是一個點由兩個像素組成.
    通常狀態下咱們設置的方式以下:

layer.contentsScale = [UIScreen mainScreen].scale;

    注意:
    當咱們能設置contentsGravity自動拉伸類狀態時,設置contentsScale是沒有效果的,由於contentsGravity已經對圖層的展現進項了拉伸適配,若是咱們須要查看設置contentsScale的效果咱們能夠將contentsGravity設置爲kCAGravityCenter;

maskToBounds

maskToBounds:
YES(不展現圖層之外的內容)
NO(展現圖層之外的內容)

    代碼示例:

layer. maskToBounds = YES;

    iOS視圖默認容許咱們將一個尺寸較大的圖層添加到一個尺寸較小的圖層上並加以展現,可是此時處於父圖層之外的子圖層區域的點擊等交互事件是監聽不到的,以及其餘展現效果的影響咱們在許多非正常佈局的狀況下咱們須要將maskToBounds設置爲YES.或者UIView的clipsToBounds屬性設置爲YES.

contentsRect

contentsRect:容許在圖層範圍內顯示寄宿圖的一個子域.
{x,y,w,h} 四個參數的取值範圍是0~1.

    默認狀態下contentsRect的取值是{0,0,1,1},也就是默認狀態下是顯示整個寄宿圖,也就是以下圖的效果.

    如我咱們將contentsRect的取值設置爲{0.5, 0.5, 0.5, 0.5},效果就變成以下圖所示:

    在app中contentsRect比較典型的用法就是圖片拼合用法,也就是咱們所須要展現的許多內容都在一張Image上,可是展現時經過contentsRect咱們將他們一一取出,這樣就極大的節約了內存的使用率.

contentsCenter

contentsCenter:並非contents的中心點,而是定義了一個固定的邊框和一個在圖層上可拉伸的區域.

    contentsCenter使用效果和UIImage裏的-resizableImageWithCapInsets: 方法效果很是相似,可是它能夠運用到任何寄宿圖,甚至包括在Core Graphics運行時繪製的圖形,在這裏就很少贅述具體的操做方法.

Custom Drawing

Custom Drawing:自定義繪製.

UIView-drawRect

    -drawRect並非一個十分陌生的方法,每當我麼自定義UIView的時候均可一看到他的身影,他的自己含以也正如咱們自定義UIView的意圖,咱們能夠經過他實現自定義繪製寄宿圖.
    -drawRect:方法是沒有被蘋果默認實現的,由於對與UIView來講,寄宿圖不是他所必須.若是UIView檢測到-drawRect:方法被實現了,那麼UIView會爲視圖分配一個寄宿圖,寄宿圖的像素尺寸等於視圖大小乘以 contentsScale的值。須要注意的是若是咱們不須要使用寄宿圖咱們不要實現-drawRect:,由於這會形成CPU以及內存的沒必要要浪費,固然apple也是這麼建議的.
    -drawRect:的調用是在視圖出如今屏幕的時候,-drawRect:利用其封裝的代碼經過CoreGraphics來繪製一個寄宿圖,當寄宿圖繪製結束後會被緩存起來,直到它須要更新的時候(經過調用-setNeedsDisplay)去從新繪製更新.

CALayer-displayLayer:&&-drawLayer:inContext:

-displayLayer:對象方法
-drawLayer:inContext:代理方法

    咱們能夠經過CALayerDelegate-drawLayer:inContext:來實現自定義繪製圖層.須要作的內容很簡單,設置layer的代理,而後實現-drawLayer:inContext:方法,當咱們須要更新繪製的時候調用-displayLayer:便可.

    注意:

  • CALayer不一樣於UIView,當圖層顯示在屏幕上時,CALayer不會自動重繪它的內容,它把重繪的決定權交給了開發者。
  • 當使用CALayerDelegate繪製寄宿圖的時候,並不會對超出邊界外的內容進行繪製。
相關文章
相關標籤/搜索