CALayer

CALayer

  1. 父類是NSObject
  • layer(圖層):在iOS中屠橄,UIView之所以能顯示在屏幕上梁厉,完全是因?yàn)樗鼉?nèi)部的一個(gè)圖層咬荷,它本身不具備顯示的功能,這個(gè)圖層(即CALayer對象)听隐,可以通過layer屬性可以訪問這個(gè)層
@property(nonatomic,readonly,retain) CALayer *layer;
  • 創(chuàng)建時(shí)間:創(chuàng)建UIView時(shí)就生成成員屬性layer
  • 顯示時(shí)間:當(dāng)UIView需要顯示到屏幕上時(shí),會調(diào)用drawRect:方法進(jìn)行繪圖哄啄,并且會將所有內(nèi)容繪制在自己的圖層上雅任,繪圖完畢后,系統(tǒng)會將圖層拷貝到屏幕上咨跌,于是就完成了UIView的顯示
  • 通過操作CALayer對象沪么,可以很方便地調(diào)整UIView的一些外觀屬性
    • 陰影
    • 圓角大小
    • 邊框?qū)挾群皖伾?/li>
    • 給圖層添加動畫,來實(shí)現(xiàn)一些比較炫酷的效果等

CALayer常見屬性

寬度和高度
@property CGRect bounds;

位置(默認(rèn)指中點(diǎn)锌半,具體由anchorPoint決定)
@property CGPoint position;

錨點(diǎn)(x,y的范圍都是0-1)禽车,決定了position的含義
@property CGPoint anchorPoint;

背景顏色(CGColorRef類型)
@property CGColorRef backgroundColor;

形變屬性
類型:CATransform3DMakeScale、CATransform3DMakeRotation等
@property CATransform3D transform;

邊框顏色(CGColorRef類型)
@property CGColorRef borderColor;

邊框?qū)挾?@property CGFloat borderWidth;

//圓角半徑
@property CGColorRef borderColor;

內(nèi)容(比如設(shè)置為圖片CGImageRef)
@property(retain) id contents;

// 超出主層邊框的都會被裁減調(diào)用
@property BOOL masksToBounds
_imageView.layer.masksToBounds = YES;

關(guān)于CALayer的疑惑

  1. 首先CALayer是定義在QuartzCore框架中的刊殉,CGImageRef殉摔、CGColorRef兩種數(shù)據(jù)類型是定義在CoreGraphics框架中的,UIColor记焊、UIImage是定義在UIKit框架中的
  • 其次QuartzCore框架和CoreGraphics框架是可以跨平臺使用的逸月,在iOS和Mac OS X上都能使用但是UIKit只能在iOS中使用

  • 為了保證可移植性,QuartzCore不能使用UIImage遍膜、UIColor碗硬,只能使用CGImageRef、CGColorRef

UIView和CALayer的選擇

  1. 如果顯示出來的東西需要跟用戶進(jìn)行交互的話瓢颅,用UIView恩尾;
  • 如果不需要跟用戶進(jìn)行交互,用UIView或者CALayer都可以
    • CALayer的性能會高一些惜索,因?yàn)樗倭耸录幚淼墓δ芴厮瘢虞p量級

position和anchorPoint

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

    • 用來設(shè)置CALayer在父層中的位置
    • 以父層的左上角為原點(diǎn)(0, 0)
      @property CGPoint position;
  • anchorPoint(定位點(diǎn),錨點(diǎn)):

    1. 決定著CALayer身上的哪個(gè)點(diǎn)會在position屬性所指的位置
    • 以自己的左上角為原點(diǎn)(0, 0)
    • 它的x巾兆、y取值范圍都是0~1猎物,默認(rèn)值為(0.5, 0.5),是比例值角塑。
    • 如默認(rèn)值(0.5, 0.5)蔫磨,即layer的中心點(diǎn)在positon位置上;若是(1圃伶,1)堤如,則是layer的右下角的點(diǎn)在position的位置上蒲列,對平常的UIView來說,錨點(diǎn)相當(dāng)于(0搀罢,0)
      @property CGPoint anchorPoint;

隱式動畫

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

    1. 根層:每一個(gè)UIView內(nèi)部都默認(rèn)關(guān)聯(lián)著一個(gè)CALayer,我們可用稱這個(gè)Layer為Root Layer(根層)
    • 非根層:所有的非Root Layer榔至,也就是手動創(chuàng)建的CALayer對象抵赢,都存在著隱式動畫
  • 幾個(gè)常見的Animatable Properties:

    1. bounds:用于設(shè)置CALayer的寬度和高度。修改這個(gè)屬性會產(chǎn)生縮放動畫
    • backgroundColor:用于設(shè)置CALayer的背景色唧取。修改這個(gè)屬性會產(chǎn)生背景色的漸變動畫
    • position:用于設(shè)置CALayer的位置铅鲤。修改這個(gè)屬性會產(chǎn)生平移動畫
  • 可以通過動畫事務(wù)(CATransaction)關(guān)閉默認(rèn)的隱式動畫效果

    // 開啟事務(wù)
    [CATransaction begin];

    // 設(shè)置動畫時(shí)長
    [CATransaction setAnimationDuration:0.5];

    // 動畫
    // 可動畫屬性
    _layer.position = CGPointMake(arc4random_uniform(250), arc4random_uniform(500));

    // 背景顏色
    _layer.backgroundColor = [self randomColor].CGColor;

    // 圓角半徑
    // 長方形的時(shí)候不能設(shè)置圓角變成圓
    // 做動畫,盡量不要使用修改圓角半徑做動畫
    _layer.cornerRadius = arc4random_uniform(50);

    // 陰影(陰影設(shè)置的效果是太陽效果)
    // 顯示陰影
    _redView.layer.shadowOpacity = 1;
    //    _redView.layer.shadowOffset = CGSizeMake(10, 10);
    _redView.layer.shadowColor = [UIColor yellowColor].CGColor;

    _redView.layer.shadowRadius = 10;

    // 邊框
    _layer.borderWidth = arc4random_uniform(10);

    _layer.borderColor = [self randomColor].CGColor;

    // 提交事務(wù)
    [CATransaction commit];

CALayer常用方法

[self.view.layer addSublayer:layer];

特殊的View

  1. UIImgeView + UIImageView圓角半徑 + 主層和contents + 裁剪 + 陰影無效,達(dá)到效果枫弟,圓形頭像
  • 默認(rèn)UIImageView的圖片不是顯示到主層的子層中,而是在content層中

時(shí)鐘實(shí)現(xiàn)案例

  • 實(shí)現(xiàn)步驟:
    • 布局控件:指針都是繞圓心旋轉(zhuǎn)邢享,所以要設(shè)置錨點(diǎn)和positon在圓心
    • 開啟計(jì)時(shí),調(diào)用時(shí)間改變方法
    • 生成日歷對象淡诗,獲取當(dāng)前時(shí)間
    • 計(jì)算時(shí)分秒轉(zhuǎn)動角度骇塘,設(shè)置形變旋轉(zhuǎn)
    • 初始化時(shí)針,分針袜漩,秒針位置
// 每秒秒針轉(zhuǎn)6°
#define kPerSecondA 6
// 每分鐘分針轉(zhuǎn)6°
#define kPerMinuteA 6

// 每小時(shí)時(shí)針轉(zhuǎn)30°
#define kPerHourA 30

// 每分鐘時(shí)針轉(zhuǎn)0.5°
#define kPerMinHourA 0.5
// 每秒分針轉(zhuǎn)0.1°
#define kPerMinSecA 0.1

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@property (weak, nonatomic)  CALayer *secLayer;

@property (weak, nonatomic)  CALayer *minLayer;

@property (weak, nonatomic)  CALayer *hourLayer;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    // 小時(shí)
    [self setUpHourLayer];

    // 分
    [self setUpMinLayer];

    // 秒
    [self setUpSecLayer];

    // 定時(shí)器
    [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeChange) userInfo:nil repeats:YES];

    // 初始化始終
    [self timeChange];
}

- (void)timeChange
{
##核心代碼
    // 獲取當(dāng)前是多少秒
    // 獲取當(dāng)前的日歷對象
    NSCalendar *calendar = [NSCalendar currentCalendar];

    // 日期組件:秒,分,小時(shí),年,月,日......
    // NSCalendarUnit:表示日期組件有哪些組成
    NSDateComponents *dataCmp = [calendar components:NSCalendarUnitSecond | NSCalendarUnitMinute | NSCalendarUnitHour fromDate:[NSDate date]];


    // 獲取分
    NSInteger minute = dataCmp.minute;
##
    // 計(jì)算下分針轉(zhuǎn)多少度
    CGFloat minA = (min * kPerMinuteA + sec * kPerMinSecA) / 180.0 * M_PI;

    // 旋轉(zhuǎn)分針
    _minLayer.transform = CATransform3DMakeRotation(minA, 0, 0, 1);


    // 獲取小時(shí)
    NSInteger hour = dataCmp.hour;

    // 計(jì)算時(shí)針轉(zhuǎn)多少度 = 當(dāng)前有多少小時(shí) * 每小時(shí)轉(zhuǎn)的度數(shù)30° + 當(dāng)前多少分鐘 * 每分鐘時(shí)針轉(zhuǎn)多少0.5
    CGFloat hourA = (hour * kPerHourA + minute * kPerMinHourA) / 180.0 * M_PI;

    // 旋轉(zhuǎn)時(shí)針
    _hourLayer.transform = CATransform3DMakeRotation(hourA, 0, 0, 1);

    // 獲取秒數(shù)
    NSInteger sec = dataCmp.second;

    // 秒針轉(zhuǎn)多少度
    CGFloat secA = (sec * kPerSecondA) / 180.0 * M_PI;

    // 旋轉(zhuǎn)秒針
    _secLayer.transform = CATransform3DMakeRotation(secA, 0, 0, 1);
}

// 秒
- (void)setUpSecLayer
{
    CALayer *layer = [CALayer layer];

    _secLayer = layer;

    layer.backgroundColor = [UIColor redColor].CGColor;

    // 繞著錨點(diǎn)旋轉(zhuǎn),設(shè)置錨點(diǎn)
    layer.anchorPoint = CGPointMake(0.5, 1);

    layer.position = CGPointMake(_imageView.bounds.size.width * 0.5, _imageView.bounds.size.height * 0.5);

    layer.bounds = CGRectMake(0, 0, 1, 80);

    [_imageView.layer addSublayer:layer];
}

// 分
- (void)setUpMinLayer
{
    CALayer *layer = [CALayer layer];

    _minLayer = layer;

    layer.cornerRadius = 4;

    layer.backgroundColor = [UIColor blackColor].CGColor;

    // 繞著錨點(diǎn)旋轉(zhuǎn),設(shè)置錨點(diǎn)
    layer.anchorPoint = CGPointMake(0.5, 1);

    layer.position = CGPointMake(_imageView.bounds.size.width * 0.5, _imageView.bounds.size.height * 0.5);

    layer.bounds = CGRectMake(0, 0, 4, 80);

    [_imageView.layer addSublayer:layer];
}

// 小時(shí)
- (void)setUpHourLayer
{
    CALayer *layer = [CALayer layer];

    _hourLayer = layer;

    layer.cornerRadius = 4;

    layer.backgroundColor = [UIColor blackColor].CGColor;

    // 繞著錨點(diǎn)旋轉(zhuǎn),設(shè)置錨點(diǎn)
    layer.anchorPoint = CGPointMake(0.5, 1);

    layer.position = CGPointMake(_imageView.bounds.size.width * 0.5, _imageView.bounds.size.height * 0.5);

    layer.bounds = CGRectMake(0, 0, 4, 75);

    [_imageView.layer addSublayer:layer];
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绪爸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子宙攻,更是在濱河造成了極大的恐慌奠货,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件座掘,死亡現(xiàn)場離奇詭異递惋,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)溢陪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門萍虽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人形真,你說我怎么就攤上這事杉编。” “怎么了咆霜?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵邓馒,是天一觀的道長。 經(jīng)常有香客問我蛾坯,道長光酣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任脉课,我火速辦了婚禮救军,結(jié)果婚禮上财异,老公的妹妹穿的比我還像新娘。我一直安慰自己唱遭,他們只是感情好戳寸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著胆萧,像睡著了一般庆揩。 火紅的嫁衣襯著肌膚如雪俐东。 梳的紋絲不亂的頭發(fā)上跌穗,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機(jī)與錄音虏辫,去河邊找鬼蚌吸。 笑死,一個(gè)胖子當(dāng)著我的面吹牛砌庄,可吹牛的內(nèi)容都是我干的羹唠。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼娄昆,長吁一口氣:“原來是場噩夢啊……” “哼佩微!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起萌焰,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奶卓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年坊萝,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片园细。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蛛勉,死狀恐怖诽凌,靈堂內(nèi)的尸體忽然破棺而出痢法,到底是詐尸還是另有隱情,我是刑警寧澤尖奔,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布膘滨,位于F島的核電站丹弱,受9級特大地震影響躲胳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜粹湃,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望歧斟。 院中可真熱鬧,春花似錦勾徽、人聲如沸咒钟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽壤追。三九已至,卻和暖如春供屉,著一層夾襖步出監(jiān)牢的瞬間行冰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工伶丐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留悼做,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓哗魂,卻偏偏與公主長得像肛走,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子录别,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

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

  • 在iOS中隨處都可以看到絢麗的動畫效果朽色,實(shí)現(xiàn)這些動畫的過程并不復(fù)雜故硅,今天將帶大家一窺ios動畫全貌。在這里你可以看...
    每天刷兩次牙閱讀 8,469評論 6 30
  • 在iOS中隨處都可以看到絢麗的動畫效果纵搁,實(shí)現(xiàn)這些動畫的過程并不復(fù)雜吃衅,今天將帶大家一窺iOS動畫全貌。在這里你可以看...
    F麥子閱讀 5,101評論 5 13
  • 概覽 在iOS中隨處都可以看到絢麗的動畫效果,實(shí)現(xiàn)這些動畫的過程并不復(fù)雜利职,今天將帶大家一窺iOS動畫全貌趣效。在這里你...
    被吹落的風(fēng)閱讀 1,554評論 1 2
  • CALayer1-簡介 本文目錄 一、什么是CALayer 二猪贪、CALayer的簡單使用 回到頂部 一跷敬、什么是CA...
    白水灬煮一切閱讀 2,574評論 0 8
  • CALayer - 在iOS中,你能看得見摸得著的東西基本上都是UIView热押,比如一個(gè)按鈕西傀、一個(gè)文本標(biāo)簽、一個(gè)文本...
    Hevin_Chen閱讀 1,136評論 0 10