圓角是一種常見UI效果設計,與直角相比要柔和許多,適合暖色調設計。而在設置圓角時會帶來一定的性能損耗,下面介紹幾種高效設置方法。
在說高效高性能方法之前,先說一下設置圓角較為常用的方法以及原理。
self.backgroundView.layer.masksToBounds = YES;
self.backgroundView.layer.cornerRadius = 3.0f;
masksToBounds屬性會調用-setMasksToBounds方法,這個方法的作用就是告訴layer將位于它之下的layer層都遮蓋住。這個是一定的,因為只有遮蓋住下面的layer的渲染,你設置的layer的圓角才不會被遮住。
cornerRadius屬性很好理解,就是給layer層傳你要設置的圓曲度數,基本上控件高度的一半就是標準圓了。當然在實際運用中設置圓角的通常會設計圓角的邊緣和邊緣的顏色,設置邊和邊顏色會涉及到離屏渲染,這肯定會影響性能。離屏渲染,指的是GPU在當前屏幕緩沖區(qū)以外新開辟一個緩沖區(qū)進行渲染操作。
高性能設置圓角一
就是使用上面所寫設置圓角的方法,甚至就是在有UITableView滾動視圖也要作死使用的話。也是有方法拯救的,那就是設置shouldRasterize屬性。
self.backgroundView.layer.masksToBounds = YES;
self.backgroundView.layer.cornerRadius = 3.0f;
self.backgroundView.layer.shouldRasterize = YES;
shouldRasterize屬性是設置光柵化,可以使離屏渲染的結果緩存到內存中存為位圖, 使用的時候直接使用緩存,節(jié)省了一直離屏渲染損耗的性能。但是如果layer及sublayers常常改變的話,它就會一直不停的渲染及刪除緩存重新 創(chuàng)建緩存,所以這種情況下建議不要使用光柵化,這樣也是比較損耗性能的。
這種方法僅僅是性能卡頓的止癢,不能算真正意義上高性能圓角。
高性能設置圓角二
性能是說的影響GPU,CPU的資源消耗,在設置圓角時cpu繪制圖像,gpu文理渲染圖形生成。
所以就有了一種投機取巧的方法,就是多加了一張透明的圖片,GPU計算多層的混合渲染blending也是會消耗 一點性能的,但比第一種方法還是好上很多的。
高性能設置圓角三
就是用Core Graphics繪制圓角得到一個image
用這種方法要分情況,如果是普通的UIview控件。
其核心原理是利用Core Graphics畫出一個你想要的圓角弧度的image,然后把這個image加載到一個UIImageView上,再把UIImageView插入視圖UIView的底部。
生成image
func Rimage_drawRectWithRoundedCorner(radius radius: CGFloat,
? ? ?borderWidth: CGFloat,
? ? ?backgroundColor: UIColor,
? ? ?borderColor: UIColor) -> UIImage {
? ? ?UIGraphicsBeginImageContextWithOptions(sizeToFit, false, UIScreen.mainScreen().scale)
? ? let context = UIGraphicsGetCurrentContext()
? ? CGContextMoveToPoint(context, 開始位置);? // 開始坐標右邊開始
? ? CGContextAddArcToPoint(context, x1, y1, x2, y2, radius);? // 這種類型的代碼重復四次
? ? ?CGContextDrawPath(UIGraphicsGetCurrentContext(), .FillStroke)
? ? let Rimage = UIGraphicsGetImageFromCurrentImageContext();
? ? UIGraphicsEndImageContext();
? ? return Rimage
}
加載UIview上
func view_addCorner(radius radius: CGFloat,
? ? ? borderWidth: CGFloat,
? ? ? backgroundColor: UIColor,
? ? ? borderColor: UIColor) {
? ? ? ?let imageView = UIImageView(image: kt_drawRectWithRoundedCorner(radius: radius,
? ? ? ?borderWidth: borderWidth,
? ? ? ?backgroundColor: backgroundColor,
? ? ? ?borderColor: borderColor))
? ? ? ?self.insertSubview(imageView, atIndex: 0)
}
還有就是常見給UIImageView加圓角,它的原理也是去處理image,同時因為uiimageview直接加載image,所以實現起來更直接方便。
核心方法只有一個,就是剪切出圓角的image
func RimageForImgView_drawRectWithRoundedCorner(radius radius: CGFloat, _ sizetoFit: CGSize) -> UIImage {
? ? ? let rect = CGRect(origin: CGPoint(x: 0, y: 0), size: sizetoFit)
? ? ? UIGraphicsBeginImageContextWithOptions(rect.size, false, ? ? UIScreen.mainScreen().scale)
? ? ? CGContextAddPath(UIGraphicsGetCurrentContext(),
? ? ? UIBezierPath(roundedRect: rect, byRoundingCorners: UIRectCorner.AllCorners,
? ? ? ?cornerRadii: CGSize(width: radius, height: radius)).CGPath)
? ? ? ?CGContextClip(UIGraphicsGetCurrentContext())
? ? ? ? self.drawInRect(rect)
? ? ? ?CGContextDrawPath(UIGraphicsGetCurrentContext(), .FillStroke)
? ? ? ?let Rimage = UIGraphicsGetImageFromCurrentImageContext();
? ? ? ?UIGraphicsEndImageContext();
? ? ? ?return Rimage
}
總結
如果項目沒有出現性能卡頓或者設置圓角視圖不多,就不用考慮太多,直接用cornerRadius解決問題就行,使用上述三種提高性能也有各自優(yōu)缺點,請考慮自己項目需求選擇。參考資料小心別讓圓角成了你列表的幀數殺手,iOS 保持界面流暢的技巧。個人整理,不喜勿噴,謝謝?。?/p>