前阵子的项目中,遇到一个需要用一个TableView展示用户状态的需求,并且用户头像为圆形。我的第一反应是利用UIImageView的layer的圆角属性来设置,即以下两行代码
layer.cornerRadius = image?.size.width * 0.5
layer.masksToBounds = true
这样写固然可以,但是只要涉及到“layer.masksToBounds”的操作必然因为其渲染效果的问题影响TableView的性能以及整个APP的流畅度,因此如果在数据量比较大的情况下要针对以上代码进行优化,这里就得用到Quartz2D的绘图了,下面直接上代码:
- 这里是基于SDWebImage对获取的网络数据进行处理
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)->())”方法,具体实现是这样的:
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)
})
}
}
注:这里处理图片是一个耗时操作,因此需要在子线程执行;由于是异步操作,因此需要利用闭包作为方法的回调的参数来获取处理完成以后的图片。
作者:胥鸿儒
demo地址:https://github.com/xuhongru/profileImageDemo
网友评论