写在前面
一般我们都会通过Layer设置图片圆角,这种方法在iOS9以前可能会发生离屏渲染,
比较消耗性能,比如当一个页面上有十几头像这样设置了圆角会明显感觉到卡顿。这种就是最常用的,也是最耗性能的。
imageView.layer.cornerRadius=20;
imageView.layer.masksToBounds=YES;
ios9.0之后对UIImageView的圆角设置做了优化,UIImageView这样设置圆角不会触发离屏渲染,ios9.0之前还是会触发离屏渲染。而UIButton还是都会触发离屏渲染。
现在优化方案就是先把图片处理成圆角,处理后再渲染;
//1.先写一个切圆角的方法,方便调用
- (void)setGraphicsCutRoundCornersWithView:(UIImageView *) imageview roundCornersSize:(CGFloat )cornersSize
{
//开始上下文
UIGraphicsBeginImageContextWithOptions(imageview.bounds.size, NO, 0.0);
[[UIBezierPath bezierPathWithRoundedRect:imageview.bounds cornerRadius:cornersSize] addClip];
[imageview drawRect:imageview.bounds];
//当前上下文
imageview.image = UIGraphicsGetImageFromCurrentImageContext();
// 结束上下文
UIGraphicsEndImageContext();
}
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *imageView=[[UIImageView alloc]initWithFrame:CGRectMake(50, 50, 300, 500)];
[imageView setImage:[UIImage imageNamed:@"aaa"]];
[self setGraphicsCutRoundCornersWithView:imageView roundCornersSize:100];//调用方法
[self.view addSubview:imageView];
}
我上面的方法是加载的本地图片,如果是网络请求的,就不行了。。。我在AFNetworking里看了看不容易实现,因为他没有completed回调方法,所以我就用SD_WebImage实现了一下。
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path=@"http://pic.yesky.com/uploadImages/2015/211/46/Y9QRRQ94U8C3.jpg";
UIImageView *imageView=[[UIImageView alloc]initWithFrame:CGRectMake(50, 50, 300, 500)];
[imageView sd_setImageWithURL:[NSURL URLWithString:path] completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
[self setGraphicsCutRoundCornersWithView:imageView roundCornersSize:100];
}];
[self.view addSubview:imageView];
}
如果是普通视图,不包含图片,可通过如下方式处理: 把背景图设置成clearColor, layer 的背景color和要渲染的视图颜色一致,设置好角度,通过颜色差异来显示出圆角的效果; 关键是把masksToBounds设置NO,就是这个家伙消耗性能;
self.view.backgroundColor = [UIColor clearColor];
// Set view.layer.backgroundColor not view.backgroundColor otherwise the background is not masked to the rounded border.
self.view.layer.backgroundColor = [UIColor whiteColor].CGColor;
self.view.layer.cornerRadius = 8;
// Huge change in performance by explicitly setting the below (even though default is supposedly NO)
self.view.layer.masksToBounds = NO;
// Performance improvement here depends on the size of your view
self.view.layer.shouldRasterize = YES;
[self.view.layer setRasterizationScale:[UIScreen mainScreen].scale];