CALayer是什么?
在iOS中,UIView是我們構(gòu)建UI的基礎(chǔ)單元,而UIView之所以可以顯示各種元素靠的就是CALayer。
當(dāng)創(chuàng)建UIView對(duì)象時(shí),UIView內(nèi)部會(huì)自動(dòng)創(chuàng)建一個(gè)層,通過UIView的layer可以獲取這個(gè)主layer,當(dāng)UIView需要顯示內(nèi)容到屏幕上時(shí),會(huì)執(zhí)行一系列繪制方法將所有內(nèi)容繪制在自己的層上,繪制完畢后,系統(tǒng)會(huì)將層拷貝到屏幕上,這樣就完成了UIView的顯示。
CALayer和UIView如何選擇?
CALayer和UIView都可以顯示內(nèi)容,那他們有什么區(qū)別?
通過類的定義可以知道CALayer是繼承自CALayer的,而UIView是繼承自UIResponder,從這我們就了解了CALayer不能響應(yīng)事件,而需要響應(yīng)事件的時(shí)候,我們就需要使用UIView,如果不需要響應(yīng)事件時(shí),兩者都可以,但是CALayer的性能會(huì)比UIView好很多。
CALayer的常見屬性
- bounds - 設(shè)置CALayer的寬度和高度
- backgroundColor - 設(shè)置CALayer的背景色
- position - 設(shè)置CALayer的中心點(diǎn)
- anchorPoint - 設(shè)置錨點(diǎn),初始值為(0.5, 0.5),它是表示位于寬高的比例,初始位置與position重合
前面幾個(gè)屬性很好理解,下面詳細(xì)記錄下anchorPoint
anchorPoint
重新設(shè)置anchorPoint,相當(dāng)于anchorPoint的坐標(biāo)不動(dòng),然后移動(dòng)frame
如果設(shè)置0,0,則需要往右下角的點(diǎn)移動(dòng)view,直到比例滿足0,0的位置
如果設(shè)置0,1,則需要往右上角移動(dòng)view,直到比例滿足0,1的位置
如果設(shè)置為1,0,則需要向左下角移動(dòng)view,直到比例滿足1,0的位置
如果設(shè)置為1,1,則需要向左上角移動(dòng)view,,直到比例滿足1,1的位置
layer如何為圖片設(shè)置圓角與陰影
我們知道,在UIImageView顯示圖片的時(shí)候,只是設(shè)置cornerRadius,是無法實(shí)現(xiàn)的,必須要加上maskToBounds=YES,這是為什么?
當(dāng)繪制一張圖片到圖層上的時(shí)候會(huì)重新創(chuàng)建一個(gè)圖層添加到當(dāng)前圖層,這樣設(shè)置圓角后,只是底圖層有圓角效果,而子圖層并沒有圓角效果,所以圓角效果是顯示不出來的,這時(shí)只有設(shè)置masksToBounds為YES時(shí),才能讓子圖層按底圖層裁剪子圖層!
那我設(shè)置了圓角效果后,再加上陰影效果,這種情況會(huì)怎么樣呢?
不難想,陰影效果肯定會(huì)失效,masksToBounds會(huì)將子視圖裁剪掉,而陰影效果恰巧是作為外邊框繪制的,這樣就會(huì)被裁剪掉
如果我們希望圖層展示圖片既有圓角又有陰影,要怎么解決呢
可以通過曲線救國,借助兩個(gè)圖層來做,容器圖層添加陰影效果
圖片圖層做圖片裁剪
下面再看下在layer層同時(shí)設(shè)置圖片與陰影的方法
在看這個(gè)問題前,我們先來看下layer如何設(shè)置圖片,以及出現(xiàn)圖片倒立的問題如何解決
- 通過contents賦值設(shè)置圖片
- (void)drawCornerAndShadow {
CALayer *photoLayer = [CALayer new];
photoLayer.bounds = bounds;
photoLayer.position = position;
photoLayer.backgroundColor = [UIColor redColor].CGColor;
photoLayer.cornerRadius = cornerRadius;
photoLayer.masksToBounds = YES;
photoLayer.borderColor = [UIColor whiteColor].CGColor;
photoLayer.borderWidth = borderW;
UIImage *image=[UIImage imageNamed:@"photo.png"];
[photoLayer setContents:(id)image.CGImage];
[self.view.layer addSublayer:photoLayer];
}
通過這種設(shè)置不會(huì)產(chǎn)生倒立的問題
- 通過layer的delegate進(jìn)行繪制
- (void)drawCornerAndShadow {
CALayer *photoLayer = [CALayer new];
photoLayer.bounds = bounds;
photoLayer.position = position;
photoLayer.backgroundColor = [UIColor redColor].CGColor;
photoLayer.cornerRadius = cornerRadius;
photoLayer.masksToBounds = YES;
photoLayer.borderColor = [UIColor whiteColor].CGColor;
photoLayer.borderWidth = borderW;
//設(shè)置CALayerDelegate
photoLayer.delegate = self;
[self.view.layer addSublayer:photoLayer];
//調(diào)用圖層setNeedDisplay,否則代理不會(huì)執(zhí)行
[photoLayer setNeedsDisplay];
}
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{
CGContextSaveGState(ctx);
UIImage *image=[UIImage imageNamed:@"photo.png"];
//注意這個(gè)位置是相對(duì)于圖層而言的不是屏幕
CGContextDrawImage(ctx, CGRectMake(0, 0, Photo_W, Photo_W), image.CGImage);
}
這種顯示圖片的方法,有幾個(gè)關(guān)鍵步驟需要做:
- 設(shè)置CALayerDelegate代理為當(dāng)前VC
- 實(shí)現(xiàn)代理并在代理中設(shè)置圖片
- 執(zhí)行l(wèi)ayer的setNeedsDisplay,否則代理不會(huì)執(zhí)行
這種情況雖然圖片顯示出來了,但是圖片確是倒立的
如何解決倒立的問題呢
首先,我們要了解為什么圖片會(huì)倒立?
因?yàn)閁IKit的坐標(biāo)系,與CoreGraphics中坐標(biāo)系不同,UIKit是x軸向右為正向,y軸向下為正向;而CoreGraphics是x軸向右為正向,y軸向上為正向。
所以解決這個(gè)問題,只需要讓圖片以x軸旋轉(zhuǎn)180度即可
- 方案一 drawLayer新增選擇方法
-(void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx{ CGContextSaveGState(ctx);
//解決圖片倒立的問題-方法1
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -Photo_W);
UIImage *image=[UIImage imageNamed:@"photo.png"];
//注意這個(gè)位置是相對(duì)于圖層而言的不是屏幕
CGContextDrawImage(ctx, CGRectMake(0, 0, Photo_W, Photo_W), image.CGImage);
}
- 方案二 設(shè)置transform
photoLayer.transform = CATransform3DMakeRotation(M_PI, 1, 0, 0);
- 方案三 通過keyPath設(shè)置tansform
[photoLayer setValue:@M_PI forKeyPath:@"transform.rotation.x"];
接下來我們來看下如果通過兩個(gè)layer完成圓角與陰影的設(shè)置
- (void)drawCornerAndShadow {
CGPoint position = CGPointMake(160, 200);
CGRect bounds = CGRectMake(0, 0, Photo_W, Photo_W);
CGFloat cornerRadius = Photo_W/2;
CGFloat borderW = 2;
CALayer *layerShadow = [CALayer new];
layerShadow.bounds = bounds;
layerShadow.position = position;
layerShadow.cornerRadius = cornerRadius;
layerShadow.shadowColor = [UIColor orangeColor].CGColor;
layerShadow.shadowOffset = CGSizeMake(2, 1);
layerShadow.shadowOpacity = 1;
layerShadow.borderColor = [UIColor yellowColor].CGColor;
layerShadow.borderWidth = borderW;
[self.view.layer addSublayer:layerShadow];
CALayer *photoLayer = [CALayer new];
photoLayer.bounds = bounds;
photoLayer.position = position;
photoLayer.backgroundColor = [UIColor redColor].CGColor;
photoLayer.cornerRadius = cornerRadius;
photoLayer.masksToBounds = YES;
photoLayer.borderColor = [UIColor whiteColor].CGColor;
photoLayer.borderWidth = borderW;
UIImage *image=[UIImage imageNamed:@"photo.png"];
[photoLayer setContents:(id)image.CGImage];
[self.view.layer addSublayer:photoLayer];
}
簡(jiǎn)簡(jiǎn)單單,完成設(shè)置
生活如此美好,今天就點(diǎn)到為止。。。