CALayer的簡單使用

文 || 張賀

  • 在iOS中号涯,你能看得見摸得著的東西基本上都是UIView,比如一個(gè)按鈕锯七、一個(gè)文本標(biāo)簽链快、一個(gè)文本輸入框、一個(gè)圖標(biāo)等等眉尸,這些都是UIView
  • 其實(shí)UIView之所以能顯示在屏幕上域蜗,完全是因?yàn)樗鼉?nèi)部的一個(gè)圖層
  • 在創(chuàng)建UIView對(duì)象時(shí)巨双,UIView內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)圖層(即CALayer對(duì)象),通過UIView的layer屬性可以訪問這個(gè)層
    @property(nonatomic,readonly,strong) CALayer *layer; // returns view's layer. Will always return a non-nil value. view is layer's delegate
  • 當(dāng)UIView需要顯示到屏幕上時(shí)霉祸,會(huì)調(diào)用drawRect:方法進(jìn)行繪圖筑累,并且會(huì)將所有內(nèi)容繪制在自己的圖層上,繪圖完畢后丝蹭,系統(tǒng)會(huì)將圖層拷貝到屏幕上慢宗,于是就完成了UIView的顯示
  • 換句話說,UIView本身不具備顯示的功能奔穿,是它內(nèi)部的層才有顯示功能

CALayer的基本使用

  • 通過操作CALayer對(duì)象镜沽,可以很方便地調(diào)整UIView的一些外觀屬性,比如:
  • 陰影
  • 圓角大小
  • 邊框?qū)挾群皖伾?/li>
  • ... ...
  • 還可以給圖層添加動(dòng)畫贱田,來實(shí)現(xiàn)一些比較炫酷的效果

陰影

  • shadowOffset(陰影的偏移量)缅茉,默認(rèn)是(0, -3)。
    /* The shadow offset. Defaults to (0, -3). Animatable. */
    @property CGSize shadowOffset;
    所以UIView自帶陰影效果男摧,但為什么看不見呢蔬墩?是因?yàn)樗牧硗庖粋€(gè)屬性

  • shadowOpacity(陰影的不透明度)默認(rèn)為0,也就是說自帶的(0, -3)的偏移量是透明的
    /* The opacity of the shadow. Defaults to 0. Specifying a value outside the
    * [0,1] range will give undefined results. Animatable. */
    @property float shadowOpacity;
    想要看見這(0, -3)的偏移量只需要把shadowOpacity設(shè)置為1
    self.purpleView.layer.shadowOpacity = 1;


    自帶的(0, -3)的偏移量

    也可以自己設(shè)置偏移量
    self.purpleView.layer.shadowOffset = CGSizeMake(20, 10);

自己設(shè)置陰影偏移量
  • shadowColor(陰影的顏色)

    /* The color of the shadow. Defaults to opaque black. Colors created
    * from patterns are currently NOT supported. Animatable. */
    @property(nullable) CGColorRef shadowColor;
    

這里要轉(zhuǎn)成CGColor耗拓?

  • 首先
    CALayer是定義在QuartzCore框架中的
    CGImageRef筹我、CGColorRef 兩種數(shù)據(jù)類型是定義在CoreGraphics框架中的
    UIColor、UIImage是定義在 UIKit框架中的

  • 其次
    QuartzCore框架和CoreGraphics框架是可以跨平臺(tái)使用的帆离,在iOS和Mac OS X上都能使用蔬蕊,但是UIKit只能在iOS中使用

  • 所以
    為了保證可移植性,QuartzCore不能使用UIColor哥谷、UIImage岸夯,只能使用CGColorRef、CGImageRef

       self.purpleView.layer.shadowColor = [UIColor orangeColor].CGColor;
    
  • shadowRadius(陰影的模糊程度)

    /* The blur radius used to create the shadow. Defaults to 3. Animatable. */
    @property CGFloat shadowRadius;
    

邊框

  • borderWidth(邊框?qū)挾龋?br> /* The width of the layer's border, inset from the layer bounds. The
    * border is composited above the layer's content and sublayers and
    * includes the effects of the `cornerRadius' property. Defaults to
    * zero. Animatable. */

    @property CGFloat borderWidth;
    
  • borderColor(邊框的顏色)
    /* The color of the layer's border. Defaults to opaque black. Colors
    * created from tiled patterns are supported. Animatable. */

    @property(nullable) CGColorRef borderColor;
    

這里的顏色也要裝換成CGColor

  self.purpleView.layer.borderWidth = 2;
  self.purpleView.layer.borderColor = [UIColor orangeColor].CGColor;

圓角

  • cornerRadius(圓角)
    /* When positive, the background of the layer will be drawn with
    * rounded corners. Also effects the mask generated by the
    * `masksToBounds' property. Defaults to zero. Animatable. */

    @property CGFloat cornerRadius;
    

注意:設(shè)置圖片圓角的時(shí)候要設(shè)置masksToBounds =YES這是因?yàn)槲覀冊O(shè)置的所有l(wèi)ayer屬性之作用在根層上layer.contents只要設(shè)置了layer.masksToBounds =YES超出根層之外的部分會(huì)被裁掉们妥。

3D

  • transform
    利用layer的transform屬性可以做一些3D動(dòng)畫
    UIView的transform屬性是CGAffineTransform類型的猜扮,而layer的transform屬性是CATransform3D類型的
CATransform3D類型
CGAffineTransform類型
//平移
self.purpleView.layer.transform = CATransform3DMakeTranslation(100, 0, 0);
//旋轉(zhuǎn)
self.purpleView.layer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
//縮放
self.purpleView.layer.transform = CATransform3DMakeScale(0.5, 0.5, 0);

當(dāng)做一些快速縮放、平移监婶、二維旋轉(zhuǎn)的時(shí)候建議使用KVC

[self.purpleView.layer setValue:@(9) forKeyPath:@"transform.scale"];

可用的keyPath

可用的keyPath

UIView和CALayer的選擇

通過CALayer旅赢,就能做出跟UIImageView一樣的界面效果
既然CALayer和UIView都能實(shí)現(xiàn)相同的顯示效果,那究竟該選擇誰好呢惑惶?

  • 其實(shí)煮盼,對(duì)比CALayer,UIView多了一個(gè)事件處理的功能带污。也就是說僵控,CALayer不能處理用戶的觸摸事件,而UIView可以
  • 所以鱼冀,如果顯示出來的東西需要跟用戶進(jìn)行交互的話报破,用UIView悠就;如果不需要跟用戶進(jìn)行交互,用UIView或者CALayer都可以
  • 當(dāng)然充易,CALayer的性能會(huì)高一些梗脾,因?yàn)樗倭耸录幚淼墓δ埽虞p量級(jí)

position和anchorPoint

  • CALayer有2個(gè)非常重要的屬性:position和anchorPoint

    /* The position in the superlayer that the anchor point of the layer's
    * bounds rect is aligned to. Defaults to the zero point. Animatable. */
    
    //用來設(shè)置CALayer在父層中的位置
    //以父層的左上角為原點(diǎn)(0, 0)
    @property CGPoint position;
    
    /* Defines the anchor point of the layer's bounds rect, as a point in
    * normalized layer coordinates - '(0, 0)' is the bottom left corner of
    * the bounds rect, '(1, 1)' is the top right corner. Defaults to
    * '(0.5, 0.5)', i.e. the center of the bounds rect. Animatable. */
    
    //稱為“定位點(diǎn)”盹靴、“錨點(diǎn)”
    //決定著CALayer身上的哪個(gè)點(diǎn)會(huì)在position屬性所指的位置
    //以自己的左上角為原點(diǎn)(0, 0)
    //它的x藐唠、y取值范圍都是0~1,默認(rèn)值為(0.5, 0.5)
    @property CGPoint anchorPoint;
    

隱式動(dòng)畫

  • 每一個(gè)UIView內(nèi)部都默認(rèn)關(guān)聯(lián)著一個(gè)CALayer鹉究,我們可用稱這個(gè)Layer為Root Layer(根層)
  • 所有的非Root Layer,也就是手動(dòng)創(chuàng)建的CALayer對(duì)象踪宠,都存在著隱式動(dòng)畫

什么是隱式動(dòng)畫自赔?

  • 當(dāng)對(duì)非Root Layer的部分屬性進(jìn)行修改時(shí),默認(rèn)會(huì)自動(dòng)產(chǎn)生一些動(dòng)畫效果
    而這些屬性稱為Animatable Properties(可動(dòng)畫屬性)

  • 列舉幾個(gè)常見的Animatable Properties:
    bounds:用于設(shè)置CALayer的寬度和高度柳琢。修改這個(gè)屬性會(huì)產(chǎn)生縮放動(dòng)畫
    backgroundColor:用于設(shè)置CALayer的背景色绍妨。修改這個(gè)屬性會(huì)產(chǎn)生背景色的漸變動(dòng)畫
    position:用于設(shè)置CALayer的位置。修改這個(gè)屬性會(huì)產(chǎn)生平移動(dòng)畫


    Animatable Properties
    - (void)viewDidLoad {
    [super viewDidLoad];
    
    CALayer *layer = [CALayer layer];
    layer.position = CGPointMake(100, 100);
    layer.bounds = CGRectMake(0, 0, 100, 100);
    layer.backgroundColor = [UIColor redColor].CGColor;
    self.layer = layer;
    [self.view.layer addSublayer:layer];
    
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    /*想要關(guān)閉隱式動(dòng)畫,首先要了解核心動(dòng)畫的原理
    任何動(dòng)畫,它都會(huì)封裝到一個(gè)事務(wù)里面.學(xué)數(shù)據(jù)庫都應(yīng)該了解事務(wù)的吧.
    什么叫事務(wù), 把很多操作綁定在一起, 必須這些操作中的每一項(xiàng)全部完成,它才能做一些事件.
    就是說,你一個(gè)動(dòng)畫全部執(zhí)行完之后,它才能執(zhí)行一些事件.
    
    動(dòng)畫的底層都是包裝到一個(gè)事務(wù)里面.
    */
    //開啟一個(gè)事務(wù)
    [CATransaction begin];
    //不需要隱式動(dòng)畫
    //[CATransaction setDisableActions:YES];
    //隨機(jī)改變位置
    self.layer.position = CGPointMake(arc4random_uniform(400), arc4random_uniform(400));
    //隨機(jī)改變大小
    self.layer.bounds = CGRectMake(0, 0, arc4random_uniform(200), arc4random_uniform(200));
    //隨機(jī)改變圓角
    self.layer.cornerRadius = arc4random_uniform(50);
    //隨機(jī)改變顏色
    self.layer.backgroundColor = [self randomColor].CGColor;
    
    [CATransaction commit];
    //還可以設(shè)置隱式動(dòng)畫執(zhí)行的時(shí)長
    [CATransaction  setAnimationDuration:3.0];
    
    /*
     總結(jié):
    1.只有非根層才有隱式動(dòng)畫
    2.只要一個(gè)屬性有Animatable屬性,它就會(huì)有隱式動(dòng)畫
     */
    
    }
    #pragma mark 返回隨機(jī)顏色
    - (UIColor *)randomColor{
    
    CGFloat r = arc4random_uniform(256) / 255.0;
    CGFloat g = arc4random_uniform(256) / 255.0;
    CGFloat b = arc4random_uniform(256) / 255.0;
    
    return [UIColor colorWithRed:r green:g blue:b alpha:1];
    
    }
    
隱式動(dòng)畫.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柬脸,一起剝皮案震驚了整個(gè)濱河市他去,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌倒堕,老刑警劉巖灾测,帶你破解...
    沈念sama閱讀 216,744評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異垦巴,居然都是意外死亡媳搪,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門骤宣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秦爆,“玉大人,你說我怎么就攤上這事憔披〉认蓿” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵芬膝,是天一觀的道長望门。 經(jīng)常有香客問我,道長锰霜,這世上最難降的妖魔是什么怒允? 我笑而不...
    開封第一講書人閱讀 58,242評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮锈遥,結(jié)果婚禮上纫事,老公的妹妹穿的比我還像新娘勘畔。我一直安慰自己,他們只是感情好丽惶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,269評(píng)論 6 389
  • 文/花漫 我一把揭開白布炫七。 她就那樣靜靜地躺著,像睡著了一般钾唬。 火紅的嫁衣襯著肌膚如雪万哪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評(píng)論 1 299
  • 那天抡秆,我揣著相機(jī)與錄音奕巍,去河邊找鬼。 笑死儒士,一個(gè)胖子當(dāng)著我的面吹牛的止,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播着撩,決...
    沈念sama閱讀 40,096評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼诅福,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拖叙?” 一聲冷哼從身側(cè)響起氓润,我...
    開封第一講書人閱讀 38,939評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎薯鳍,沒想到半個(gè)月后咖气,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挖滤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,573評(píng)論 2 333
  • 正文 我和宋清朗相戀三年采章,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壶辜。...
    茶點(diǎn)故事閱讀 39,745評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡悯舟,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出砸民,到底是詐尸還是另有隱情抵怎,我是刑警寧澤岭参,帶...
    沈念sama閱讀 35,448評(píng)論 5 344
  • 正文 年R本政府宣布演侯,位于F島的核電站,受9級(jí)特大地震影響悬赏,放射性物質(zhì)發(fā)生泄漏闽颇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,048評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望衅斩。 院中可真熱鬧怠褐,春花似錦惫搏、人聲如沸蚕涤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽天吓。三九已至,卻和暖如春汰规,著一層夾襖步出監(jiān)牢的瞬間物邑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評(píng)論 1 269
  • 我被黑心中介騙來泰國打工茂嗓, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留述吸,地道東北人锣笨。 一個(gè)月前我還...
    沈念sama閱讀 47,776評(píng)論 2 369
  • 正文 我出身青樓朴读,卻偏偏與公主長得像衅金,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鉴吹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,652評(píng)論 2 354

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

  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜瞒渠,今天將帶大家一窺ios動(dòng)畫全貌伍玖。在這里你可以看...
    每天刷兩次牙閱讀 8,485評(píng)論 6 30
  • 在iOS中隨處都可以看到絢麗的動(dòng)畫效果嫩痰,實(shí)現(xiàn)這些動(dòng)畫的過程并不復(fù)雜,今天將帶大家一窺iOS動(dòng)畫全貌串纺。在這里你可以看...
    F麥子閱讀 5,110評(píng)論 5 13
  • 前言 本文只要描述了iOS中的Core Animation(核心動(dòng)畫:隱式動(dòng)畫、顯示動(dòng)畫)纺棺、貝塞爾曲線、UIVie...
    GitHubPorter閱讀 3,621評(píng)論 7 11
  • Core Animation是一個(gè)復(fù)合引擎祷蝌,它的職責(zé)就是盡可能快地組合屏幕上不同的可視內(nèi)容,這個(gè)內(nèi)容是被分解成獨(dú)立...
    abb266389fd0閱讀 1,116評(píng)論 2 17
  • 轉(zhuǎn)載:http://www.reibang.com/p/18c306333080 1.UIView與CALayer...
    F麥子閱讀 535評(píng)論 0 1