在iOS中都會牽扯到圖形轉(zhuǎn)換,動畫效果脏毯,添加視圖闹究,等等的一系列問題,在設(shè)計頁面食店,設(shè)計圖形渣淤,添加動畫的時候都會使用到這個知識。
簡單的說他就是視圖的圖層叛买,但又不是視圖砂代,因為視圖可以和用戶交互,添加響應(yīng)事件率挣,添加視圖等等,但是CALayer并不可以添加響應(yīng)事件等等露戒,它只是一個視圖的圖層椒功,就是這個圖片的顯示層捶箱,展示層,只能夠顯示內(nèi)容动漾,比如展示背景顏色丁屎,展示圖片,設(shè)置邊框旱眯,等等晨川。
- UIView上面的rootLayer 發(fā)生改變的話 子圖層也會發(fā)生變化
- 如果想要改變 button的視圖形狀邊框等,要改變的不止有一個視圖 改變的只是其中一個視圖的rootLayer 它會顯示出顯示未被裁切的邊框
- rootLayer上面沒有動畫效果
- CALayer發(fā)生改變 子圖層不會跟隨發(fā)生改變 自帶動畫效果(當(dāng)改變屬性值的時候) 隱式動畫
理解了CALayer之后就可以大致的有一個了解删豺,有個要使用的方向共虑,而且單獨對圖層做設(shè)計修改的時候功能也會比以前多很多,而且當(dāng)你改變他的圖層數(shù)值的時候呀页,CALayer是自帶隱式動畫效果的
接下來看一個圖來大概了解下視圖的圖層關(guān)系妈拌,下面是我某一個頁面的3D圖,不得不說Xcode的強大
在左邊我們可以詳細(xì)看到他們的圖層是怎么樣嵌套的蓬蝶,當(dāng)你選中一個圖層的時候你也可以在上面看到他的所有父視圖尘分,或者說在他之前有幾層圖層,分別是什么丸氛,當(dāng)你對一個視圖進(jìn)行處理的時候培愁,打算處理他的哪一個圖層,都很重要缓窜。
如果你只處理了一層竭钝,比如我為了美觀,我想把上圖collectionView上面的cell設(shè)置了這個屬性
cell.layer.cornerRadius = 10;
他就會有一點圓邊雹洗,讓用戶感覺上至少比方方正正的好看很多香罐,但是我cell上面還有一層imageView和label,他們都在contentView上面时肿,在這兩個屬性都為空的時候庇茫,cell沒有問題,但一旦我設(shè)置了圖片螃成,而且是填滿狀態(tài)的旦签,顯示圖片是沒有問題,但是你會發(fā)現(xiàn)這個cell他又變成方方正正的了寸宏,??這難免會讓人很煩躁宁炫,有時候確實會因為各種原因頭疼,甚至因此卡住氮凝,或者放棄這個效果羔巢,白白浪費了一段時間。
感覺有點像打廣告的。竿秆。所以你要設(shè)置的時候要清楚的知道自己要對哪一個圖層進(jìn)行處理启摄,在這里我們只要再給他的ImageView層處理一下layer就可以了
cell.imageView.layer.cornerRadius = 10;
//裁切內(nèi)容的尺寸
cell.imageView.layer.masksToBounds = YES;
接下來說一下圖層的一些屬性,可修改的一些屬性
- bounds 邊境范圍
- position 中心點
- zPosition z軸中心點
- anchorPoint 錨點 ?????
- 錨點 默認(rèn)錨點是與中心店重合 錨點的最小值是0幽钢,0最大值1歉备,1 默認(rèn)值是0.5,0.5
- 當(dāng)視圖 改變的時候 是以錨點為基準(zhǔn)去改變
- 錨點的值與位置
- anchorPointZ Z軸錨點
- transform 轉(zhuǎn)換形態(tài)
- frame NO. Animatable 坐標(biāo)
- hidden 隱藏
- doubleSided 圖層背面是否顯示
- geometryFlipped 翻轉(zhuǎn) 顛倒
- masksToBounds 裁切邊境
- contents 內(nèi)容
- opaque 不透明度
- allowsEdgeAntialiasing 是否使用 變形后的抗鋸齒
- backgroundColor 背景顏色
- borderWidth 邊框?qū)?/li>
- borderColor 邊框顏色
- opacity 不透明度
- shadowColor 陰影顏色
- shadowOpacity 陰影不透明度
- rasterizationScale 防止Retina屏幕像素化
- shadowOffset 陰影偏移量
- shadowRadius 陰影的半徑
通過設(shè)置這些屬性都可以讓視圖的形態(tài)等發(fā)生改變匪燕,要注意在給CALayer一些屬性賦值的時候蕾羊,他需要的值得類型都是一些特殊類型的值
比如我們之前在給View的transform賦值的時候使用的都是CGAffineTransform類型的,而給CALayer的transform賦值的時候使用使用的是CATransform3D類型的值帽驯,包括改變背景顏色也是使用的CGColor,圖片是CGImageRef所以使用的時候要注意界拦。
在給他們修改屬性的時候吸申,因為CALayer自帶隱式動畫,所以在觸發(fā)事件等改變他的屬性的時候都會自帶動畫效果享甸。
在下面要具體說一下CALayer里面的錨點屬性,也是動畫蛉威,視圖效果使用最重要的一個屬性
大家如果有用過UIView的一些animation的基礎(chǔ)動畫的時候可能會知道哲虾,沒用過也沒關(guān)系,你肯定知道移動視圖都是調(diào)整視圖的center值來做到使視圖移動到另外一個位置栅盲,設(shè)置bounds來放大或縮小一個視圖汪诉。這里我們不重點說這個扒寄。
在這里錨點和視圖的center值有點類似,也是通過知道他的中心點拟烫,來設(shè)置這個中心點该编,來改變他的位置,不過在這里我們不用中心點了硕淑,用的就是錨點來替代了這個點课竣,他可以讓視圖以任意點為挪動點嘉赎,比如,一個長長的汽車在行駛稠氮,汽車上面的人的位置都是固定不變的曹阔,你可以通過改變汽車的中心點來讓汽車移動半开,也可以通過某一個人的位置的改變來改變汽車的位置隔披,比如我現(xiàn)在想讓這個汽車通過一個山洞
比如星星是司機,在這里我可以通過這個司機的位置寂拆,把司機的X增加一定的數(shù)值來讓這個車通過這個山洞奢米,和通過改變中心點是一個道理,只不過是這個中心點變了纠永,變成了我們定義的一個錨點鬓长。也可以理解成把牛栓在樹上,他怎么跑也跑不出這個點尝江,以這個點為移動點來做動作涉波。
理解了這個點的含義,就能做很多事情炭序,比如有些動畫就是通過固定錨點來讓視圖做一些動作
原諒我做不出動圖T T啤覆,沒有美工,在這里我設(shè)置圖片的旋轉(zhuǎn)就是讓他轉(zhuǎn)動半個圓惭聂,但是我把它的錨點設(shè)置成了他的右下角窗声,所以他會以右下角來轉(zhuǎn)動。
我們簡單的寫一個實例的layer
我們把CALayer定義成一個全局變量
{
CALayer *layer;
}
layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 100, 100);
layer.backgroundColor = [UIColor colorWithRed:1.000 green:0.607 blue:0.468 alpha:1.000].CGColor;
//在這里注意我們要添加的是一個layer所以要把它添加到我們要修改視圖的layer上面
[self.view.layer addSublayer:layer];
然后我們寫一個touchBegan的方法
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
CGFloat width = CGRectGetWidth(layer.bounds)!=100?100:25;
layer.bounds = CGRectMake(0, 0, width, width);
layer.cornerRadius = layer.cornerRadius !=50 ? 50:0;
layer.position = [touch locationInView:self.view];
}
在這里我們也簡單寫一個錨點的使用辜纲,我們繼續(xù)定義一個CALayer
@property (nonatomic,strong)CALayer *pointLayer;
self.pointLayer.anchorPoint = CGPointMake(0.5 , 0.9);
self.pointLayer.contents = (id)[UIImage imageNamed:@"要旋轉(zhuǎn)的圖片"].CGImage;
- (CALayer *)pointLayer{
if (_pointLayer) {
return _pointLayer;
}
_pointLayer = [CALayer layer];
[self.view.layer addSublayer:_pointLayer];
_pointLayer.bounds = CGRectMake(0, 0, 20, 160);
_pointLayer.position = self.view.center;
return _pointLayer;
}
我們這個圖片是一個寬20笨觅,高160的圖片,我還是放一個圖吧耕腾,免得被罵见剩。。
嗯扫俺。苍苞。大概就是這個形狀,好的牵舵,錨點是以圖層的比例來定義的柒啤,我定義的是X軸比例0.5,Y比例0.9畸颅,也就是說担巩,這個點大概在X是一半,Y是0.9没炒,就是把這個圖從上到下分成10份涛癌,他在第9份那個位置,大概在如圖位置,咳咳拳话。先匪。然后,我們讓他來進(jìn)行一個旋轉(zhuǎn)弃衍,正常的旋轉(zhuǎn)應(yīng)該都是以中心點來旋轉(zhuǎn)呀非,大概畫面就像孫悟空耍金箍棒一樣,以中心來旋轉(zhuǎn)
我們來設(shè)置一個方法通過定時器來調(diào)用它
- (void)start{
// NSCalendar日歷的一個類镜盯,可以通過它獲得年月日 時分秒
// NSCalendar
// NSDateComponents 組件 fromDate 獲得哪個日期的組件
NSCalendar *calendar = [NSCalendar currentCalendar];
// @property NSInteger hour;
// @property NSInteger minute;
// @property NSInteger second;
NSDateComponents *components = [calendar components:NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:[NSDate date]];
float s = components.second * 6;
//在layer上面添加transform使用的都是CATransform3D
//X Y Z是設(shè)置繞哪個軸來旋轉(zhuǎn)的 第一個值是旋轉(zhuǎn)的角度
self.pointLayer.transform = CATransform3DMakeRotation(s, 0, 0, 1);
}
然后我們在viewDidLoad添加一個定時器
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(start) userInfo:nil repeats:YES];
現(xiàn)在他就可以繞點來進(jìn)行旋轉(zhuǎn)了
具體每個屬性都可以自己試一下他的效果岸裙,然后發(fā)一個有助于理解錨點的demo
最后說一下iOS的核心動畫也是通過這個圖層來實現(xiàn)的,下次把鏈接貼上
再貼上一個圖層效果的一些處理處理圖層特效