你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS-圓角設置性能優化

iOS-圓角設置性能優化

編輯:IOS開發綜合

查閱了好些關於圓角性能優化的帖子,總結下記錄下來.
首先:
DSImageViewRound 使用方法
iOS圖片高性能設置圓角

一般我們在iOS開發的過程中設置圓角都是如下這樣設置的。

 avatarImageView.clipsToBounds = YES;
 [avatarImageView.layer setCornerRadius:50];

這樣設置會觸發離屏渲染,比較消耗性能。比如當一個頁面上有十幾頭像這樣設置了圓角
會明顯感覺到卡頓。

注意:png圖片UIImageView處理圓角是不會產生離屏渲染的。(ios9.0之後不會離屏渲染,ios9.0之前還是會離屏渲染)。
所以如果要高性能的設置圓角就需要找另外的方法了。下面是我找到的一些方法

設置圓角的方法

1.直接使用setCornerRadius

這種就是最常用的,也是最耗性能的。

2.setCornerRadius設置圓角之後,shouldRasterize=YES光柵化


avatarImageView.clipsToBounds = YES; 
[avatarImageView.layer setCornerRadius:50]; avatarImageView.layer.shouldRasterize = YES;

shouldRasterize=YES設置光柵化,可以使離屏渲染的結果緩存到內存中存為位圖, 使用的時候直接使用緩存,節省了一直離屏渲染損耗的性能。

但是如果layer及sublayers常常改變的話,它就會一直不停的渲染及刪除緩存重新 創建緩存,所以這種情況下建議不要使用光柵化,這樣也是比較損耗性能的。

3.投機取巧方法:->直接覆蓋一張中間為圓形透明的圖片

這種方法就是多加了一張透明的圖片,GPU計算多層的混合渲染blending也是會消耗 一點性能的,但比第一種方法還是好上很多的。

4.UIImage drawInRect繪制圓角

這種方式GPU損耗低內存占用大,而且UIButton上不知道怎麼繪制,可以用 UIimageView添加個點擊手勢當做UIButton使用。

UIGraphicsBeginImageContextWithOptions(avatarImageView.bounds.size, NO, [UIScreen mainScreen].scale);
  [[UIBezierPath bezierPathWithRoundedRect:avatarImageView.bounds cornerRadius:50] addClip];
  [image drawInRect:avatarImageView.bounds];
  avatarImageView.image = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();

這段方法可以寫在SDWebImage的completed回調裡,在主線程異步繪制。 也可以封裝到UIImageView裡,寫了個DSRoundImageView。後台線程異步繪制,不會阻塞主線程。

5.SDWebImage處理圖片時Core Graphics繪制圓角

//UIImage繪制為圓角

  int w = imageSize.width;
  int h = imageSize.height;
  int radius = imageSize.width/2;  
  UIImage *img = image;
  CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 4 * w, colorSpace, kCGImageAlphaPremultipliedFirst);
  CGRect rect = CGRectMake(0, 0, w, h);
  CGContextBeginPath(context);
  addRoundedRectToPath(context, rect, radius, radius);
  CGContextClosePath(context);
  CGContextClip(context);
  CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);
  CGImageRef imageMasked = CGBitmapContextCreateImage(context);
  img = [UIImage imageWithCGImage:imageMasked];
  CGContextRelease(context);
  CGColorSpaceRelease(colorSpace);
  CGImageRelease(imageMasked);

以上代碼我寫成了UIImage的類別:UIImage+DSRoundImage.h 並在SDWebImage庫裡處理image的時候使用類別方法繪制圓角並緩存。
此分類github地址:https://github.com/walkdianzi/DSRoundedImageArticle
使用Instruments的Core Animation查看性能

Color Offscreen-Rendered Yellow

開啟後會把那些需要離屏渲染的圖層高亮成黃色,這就意味著黃色圖層可能存在性能問題。
Color Hits Green and Misses Red

如果shouldRasterize被設置成YES,對應的渲染結果會被緩存,如果圖層是綠色,就表示這些緩存被復用;如果是紅色就表示緩存會被重復創建,這就表示該處存在性能問題了。
用Instruments測試得

第一種方法,ios9.0之前UIImageView和UIButton都高亮為黃色。ios9.0之後只有UIButton高亮為黃色。

第二種方法UIImageView和UIButton都高亮為綠色

第三種方法,無任何高亮,說明沒離屏渲染。 這種圓片覆蓋的方法一般只用在底色為純色的時候,如果圓角圖片的父View是張圖片的時候就沒辦法了,而且底色如果是多種顏色的話那 要做多張不同顏色的圓片覆蓋。(可以用代碼取底色的顏色值給圓片著色)

第四種方法無任何高亮,說明沒離屏渲染(但是CPU消耗和內存占用會很大)

第五種方法無任何高亮,說明沒離屏渲染,而且內存占用也不大。(暫時感覺是最優方法)

集錦2:
一行代碼,圓角風雨無阻,告別離屏渲染性能損耗
github碉堡了鏈接:https://github.com/liuzhiyi1992/ZYCornerRadius

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved