[iOS]UIImageView增加圓角
"如何給一個UIImageView增加圓角?有幾種方法?各自區別?"
備注:本文參考自http://www.jianshu.com/p/d1954c9a4426
UIImageView *poImgView = [[UIImageView alloc]init];
方案A(基本方案):
poImgView.layer.cornerRadius = poImgView.frame.size.width/2.0; poImgView.layer.masksToBounds = YES; (或者 poImgView.clipsToBounds = YES;)
備注:clipsToBounds是對view的切割,masksToBounds是對layer的切割
性能消耗:
這個是離屏渲染(off-screen-rendering),對性能消耗比較大
fps大致在45幀左右(每個cell 做2個imageview)
正常fps是60幀,越小,用戶體驗越差
|
離屏渲染,指的是GPU在當前屏幕緩沖區以外新開辟一個緩沖區進行渲染操作。由上面的一個結論視圖和圓角的大小對幀率並沒有什么卵影響,數量才是傷害的核心輸出啊。可以知道離屏渲染耗時是發生在離屏這個動作上面,而不是渲染。為什么離屏這么耗時?原因主要有創建緩沖區和上下文切換。創建新的緩沖區代價都不算大,付出最大代價的是上下文切換。
方案B:
CAShapeLayer *layer = [CAShapeLayer layer]; UIBezierPath *aPath = [UIBezierPath bezierPathWithOvalInRect:aImageView.bounds]; layer.path = aPath.CGPath; poImgView.layer.mask = layer;
性能消耗:
測試fps大致在20幀左右,比方案A的消耗更大
方案C:
- (UIImage *)imageWithCornerRadius:(CGFloat)radius { CGRect rect = (CGRect){0.f, 0.f, self.size}; UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale); CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath); CGContextClip(UIGraphicsGetCurrentContext()); [self drawInRect:rect]; UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
性能消耗:
這個是on-screen-rendering
相當於時時去做渲染,相比於A.B方案的離線渲染,此方法對性能消耗最低,推薦用此方案。
說明
方案A和方案B都是比較常見的方式,但是都不推薦,對此的優化方案是是用C,但是如果費用使用A或者B方案,補救措施是:
1.柵格化:將cell的所有內容生成一張獨立的圖像,在屏幕滾動時,只顯示圖像;這將隱式的創建一個位圖,各種陰影遮罩等效果也會保存到位圖中並緩存起來,從而減少渲染的頻度(不是矢量圖);這個命令會讓視圖渲染的內容被緩存下來,下一次繪制的時候直接顯示緩存。
self.layer.shouldRasterize = YES;
2.指定分辨率,否則默認使用 *1 的圖像,需要指定和屏幕相匹配的分辨率
self.layer.rasterizationScale = [UIScreen mainScreen].scale;
