UITableViewCell 性能優(yōu)化之切圓角
圓角頭像,在很多 App 中都很常見沼撕。
無非就是現(xiàn)實(shí)一張圓形的圖片贯吓。
做方便的做法是使用cornerRadius屬性來切圓角鳞溉。
UIImageView*iv = [[UIImageViewalloc] initWithFrame:CGRectMake(0,0,200,200)];iv.center =self.view.center;iv.layer.cornerRadius = iv.bounds.size.width *0.5;iv.layer.masksToBounds =YES;[self.view addSubview:iv];iv.image = [UIImageimageNamed:@"lzy.jpg"];
界面:
使用 cornerRadius "切"出來的圓角
perfect!靠益!一張圓角圖片就切出來了丧肴。
這有什么難的?so easy 啊胧后。
我也沒做什么特別大的努力啊芋浮。圓角和性能優(yōu)化有啥關(guān)系,不就是一個(gè)屬性嗎壳快?
使用 cornerRadius 會(huì)產(chǎn)生什么問題纸巷?為什么談到切圓角性能優(yōu)化的時(shí)候,必須說道這個(gè)屬性眶痰?
我們打開這個(gè) UI 界面的層次結(jié)構(gòu)的觀察瘤旨。
image.png
發(fā)現(xiàn),切了圓角的圖片竖伯,外圍仍然有個(gè)矩形存哲。
感覺像是并沒有把矩形切了個(gè)原形,而是把四個(gè)角的內(nèi)容變成透明的了七婴?
紅色 = 混合圖層 = 透明處理 = 更多的 GPU 消耗
打開模擬器的 Color Blended Layers(混合圖層),發(fā)現(xiàn)UIImageView 的這一片是紅色祟偷。
模擬器只要出現(xiàn)了紅色,就表明這一片做了透明處理打厘。
如果是單單一張圖片修肠,且位置從始至終不發(fā)生變化,OK 啦户盯。沒什么大問題嵌施。
但是如果,是一張?jiān)?UITableViewCell 上的圖片莽鸭,且 Cell 在快速滑動(dòng)的時(shí)候吗伤。
那么 GPU 就無時(shí)不刻的都要計(jì)算這個(gè)透明度。因?yàn)橐@示和兩個(gè)圖層的綜合信息硫眨。
這無疑會(huì)消耗一部分 GPU 的性能足淆。如果這種混合的情況太多的話,一定會(huì)造成 Cell 滑動(dòng)時(shí)候的卡頓了。
現(xiàn)在問題:
我們需要一個(gè)圓角的圖片缸浦,但是使用cornerRadius切了個(gè)假圓角,實(shí)際上是把四周透明了氮兵。
有透明就有混合圖層裂逐。
有混合圖層,GPU 計(jì)算量就會(huì)變大泣栈。
圖層固定還好卜高,如果圖層一直在移動(dòng)(cell 滾動(dòng)),那么對 GPU 來說是一個(gè)性能考驗(yàn)南片。
要解決的:
我要一張圓形的圖片掺涛。
不要使用cornerRadius。
真真正正的把四個(gè)角給切了疼进。
不使用混合圖層薪缆,減少 GPU 的壓力 提高性能。
解決思路
目標(biāo):
既然伞广,使用cornerRadius拣帽,做的是假切割,造成了透明&混合圖層嚼锄。
我們就需要一種真切割的方式减拭。
真真正正的把圖片的四個(gè)角給切了。
不再是cornerRadius會(huì)造成透明区丑。
解決方案:
使用核心繪圖 + 貝塞爾圓形切割 產(chǎn)生一張新真正切割過四個(gè)角的圖圖片就好了拧粪。
貼代碼
- (void)rl_cornerImageWithSize:(CGSize)size fillColor:(UIColor*)fillColor complectionBlock:(void(^)(UIImage*))complectionBlock {// 耗時(shí)操作放在異步線程dispatch_async(dispatch_get_global_queue(0,0), ^{// 1. 獲取圖片畫板UIGraphicsBeginImageContextWithOptions(size,YES,0);// 2. 填充畫板的底色[fillColor setFill];CGRectrect =CGRectMake(0,0, size.width, size.height);UIRectFill(rect);// 3. 開始裁切。矩形圓形路徑UIBezierPath*path = [UIBezierPathbezierPathWithOvalInRect:rect];? ? ? ? [path addClip];// 4. 在底色上畫圖[selfdrawInRect:rect];// 5. 從畫板獲取圖片UIImage*resultImage =UIGraphicsGetImageFromCurrentImageContext();// 6. 關(guān)閉上下文UIGraphicsEndImageContext();// 7. 回到主線程沧侥,返回圖片可霎。dispatch_async(dispatch_get_main_queue(), ^{if(complectionBlock) {? ? ? ? ? ? ? ? complectionBlock(resultImage);? ? ? ? ? ? }? ? ? ? });? ? });}
UIImageView*iv = [[UIImageViewalloc] initWithFrame:CGRectMake(0,0,200,200)];iv.center =self.view.center;[self.view addSubview:iv];[[UIImageimageNamed:@"lzy.jpg"] rl_cornerImageWithSize:iv.bounds.size fillColor:[UIColorwhiteColor] complectionBlock:^(UIImage*resultImage) {? iv.image = resultImage;}];
運(yùn)行看效果:
最終效果
達(dá)成目標(biāo):
需要一個(gè)切了圓角的圖片 。[√ ]
不要產(chǎn)生混合圖層正什。[√ ]
作者:Just_relax
鏈接:http://www.reibang.com/p/a6e51965d51b
來源:簡書
簡書著作權(quán)歸作者所有啥纸,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。