前陣子的項目中,遇到一個需要用一個TableView展示用戶狀態(tài)的需求,并且用戶頭像為圓形栅组。我的第一反應(yīng)是利用UIImageView的layer的圓角屬性來設(shè)置,即以下兩行代碼
layer.cornerRadius = image?.size.width * 0.5
layer.masksToBounds = true
這樣寫固然可以枢析,但是只要涉及到“l(fā)ayer.masksToBounds”的操作必然因為其渲染效果的問題影響TableView的性能以及整個APP的流暢度玉掸,因此如果在數(shù)據(jù)量比較大的情況下要針對以上代碼進行優(yōu)化,這里就得用到Quartz2D的繪圖了司浪,下面直接上代碼:
- 這里是基于SDWebImage對獲取的網(wǎng)絡(luò)數(shù)據(jù)進行處理
func getRoundProfileImage(urlString:String)
{
SDWebImageDownloader.sharedDownloader().downloadImageWithURL(NSURL(string: urlString), options: SDWebImageDownloaderOptions(rawValue: 0), progress: { (_, _) -> Void in
}) { (image, _, _, _) -> Void in
if image != nil
{
image.roundProfile({ (roundImage) -> () in
self.image = roundImage
})
}
else
{
UIImage(named: "avatar_default_big")?.roundProfile({ (roundImage) -> () in
self.image = roundImage
})
}
}
}
- 這里是對image的處理,也就是上文中的“roundProfile(success:(roundImage:UIImage)->())”方法把沼,具體實現(xiàn)是這樣的:
func roundProfile(success:(roundImage:UIImage)->())
{
dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
let size:CGSize = self.size
//開啟圖片上下文
UIGraphicsBeginImageContextWithOptions(size, false, 0)
let ctx = UIGraphicsGetCurrentContext()
//繪制路徑
let path = UIBezierPath()
//描述路徑
path.addArcWithCenter(CGPoint(x: size.width * 0.5,y: size.height * 0.5), radius: size.height * 0.5, startAngle: 0.0, endAngle: CGFloat(M_PI) * 2, clockwise: false)
CGContextAddPath(ctx, path.CGPath)
CGContextClip(ctx)
self.drawAtPoint(CGPointZero)
let clipImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
dispatch_async(dispatch_get_main_queue(), { () -> Void in
success(roundImage: clipImage)
})
}
}
注:這里處理圖片是一個耗時操作啊易,因此需要在子線程執(zhí)行;由于是異步操作饮睬,因此需要利用閉包作為方法的回調(diào)的參數(shù)來獲取處理完成以后的圖片租谈。
作者:胥鴻儒
demo地址:https://github.com/xuhongru/profileImageDemo