W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
給contents
賦CGImage的值不是唯一的設(shè)置寄宿圖的方法。我們也可以直接用Core Graphics直接繪制寄宿圖。能夠通過繼承UIView并實(shí)現(xiàn)-drawRect:
方法來自定義繪制。
-drawRect:
方法沒有默認(rèn)的實(shí)現(xiàn),因?yàn)閷IView來說,寄宿圖并不是必須的,它不在意那到底是單調(diào)的顏色還是有一個(gè)圖片的實(shí)例。如果UIView檢測到-drawRect:
方法被調(diào)用了,它就會(huì)為視圖分配一個(gè)寄宿圖,這個(gè)寄宿圖的像素尺寸等于視圖大小乘以 contentsScale
的值。
如果你不需要寄宿圖,那就不要?jiǎng)?chuàng)建這個(gè)方法了,這會(huì)造成CPU資源和內(nèi)存的浪費(fèi),這也是為什么蘋果建議:如果沒有自定義繪制的任務(wù)就不要在子類中寫一個(gè)空的-drawRect:方法。
當(dāng)視圖在屏幕上出現(xiàn)的時(shí)候 -drawRect:
方法就會(huì)被自動(dòng)調(diào)用。-drawRect:
方法里面的代碼利用Core Graphics去繪制一個(gè)寄宿圖,然后內(nèi)容就會(huì)被緩存起來直到它需要被更新(通常是因?yàn)殚_發(fā)者調(diào)用了-setNeedsDisplay
方法,盡管影響到表現(xiàn)效果的屬性值被更改時(shí),一些視圖類型會(huì)被自動(dòng)重繪,如bounds
屬性)。雖然-drawRect:
方法是一個(gè)UIView方法,事實(shí)上都是底層的CALayer安排了重繪工作和保存了因此產(chǎn)生的圖片。
CALayer有一個(gè)可選的delegate
屬性,實(shí)現(xiàn)了CALayerDelegate
協(xié)議,當(dāng)CALayer需要一個(gè)內(nèi)容特定的信息時(shí),就會(huì)從協(xié)議中請求。CALayerDelegate是一個(gè)非正式協(xié)議,其實(shí)就是說沒有CALayerDelegate @protocol可以讓你在類里面引用啦。你只需要調(diào)用你想調(diào)用的方法,CALayer會(huì)幫你做剩下的。(delegate
屬性被聲明為id類型,所有的代理方法都是可選的)。
當(dāng)需要被重繪時(shí),CALayer會(huì)請求它的代理給他一個(gè)寄宿圖來顯示。它通過調(diào)用下面這個(gè)方法做到的:
(void)displayLayer:(CALayerCALayer *)layer;
趁著這個(gè)機(jī)會(huì),如果代理想直接設(shè)置contents
屬性的話,它就可以這么做,不然沒有別的方法可以調(diào)用了。如果代理不實(shí)現(xiàn)-displayLayer:
方法,CALayer就會(huì)轉(zhuǎn)而嘗試調(diào)用下面這個(gè)方法:
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx;
在調(diào)用這個(gè)方法之前,CALayer創(chuàng)建了一個(gè)合適尺寸的空寄宿圖(尺寸由bounds
和contentsScale
決定)和一個(gè)Core Graphics的繪制上下文環(huán)境,為繪制寄宿圖做準(zhǔn)備,他作為ctx參數(shù)傳入。
讓我們來繼續(xù)第一章的項(xiàng)目讓它實(shí)現(xiàn)CALayerDelegate并做一些繪圖工作吧(見清單2.5).圖2.12是他的結(jié)果
清單2.5 實(shí)現(xiàn)CALayerDelegate
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
?
//create sublayer
CALayer *blueLayer = [CALayer layer];
blueLayer.frame = CGRectMake(50.0f, 50.0f, 100.0f, 100.0f);
blueLayer.backgroundColor = [UIColor blueColor].CGColor;
//set controller as layer delegate
blueLayer.delegate = self;
//ensure that layer backing image uses correct scale
blueLayer.contentsScale = [UIScreen mainScreen].scale; //add layer to our view
[self.layerView.layer addSublayer:blueLayer];
//force layer to redraw
[blueLayer display];
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
//draw a thick red circle
CGContextSetLineWidth(ctx, 10.0f);
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextStrokeEllipseInRect(ctx, layer.bounds);
}
@end
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: