前言:
最近面试,有许多公司都会问这么一个问题:说说你怎么设置圆角图标的(不要说cornerRadius),相信许多人也碰到过这个问题,今天就总结一下关于圆角图标的设置问题.
cornerRadius方式设置圆角
//
// ViewController.m
// 圆角图标
//
// Created by James on 16/3/24.
// Copyright © 2016年 Apple. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//新建一个redView
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
//设置imageView的image并居中
imageView.image = [[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"avatar" ofType:@"jpg"]];
imageView.center = self.view.center;
//添加到父控件上
[self.view addSubview:imageView];
}
@end
虽然这种方法很简单,但却是以牺牲性能为代价的,如果在tableView中使用这种方法设置头像,会导致cell在每次重用的时候都重新计算图片尺寸并进行切割,浪费过多的系统资源,导致每次滑动tableView的时候造成卡顿,影响用户体验.检验:
利用模拟器中的Debug中的ColorMisaligned Images选项,可以看到下图效果:
说明在显示时,图片大小与容器大小不符,被拉伸过.
利用Debug中的Color Blended Layers 可以看到那些红色部分,就是造成浪费资源浪费的罪魁祸首,他们是透明的layer
我们就是要把这些没有必要是透明的部分解决掉,快速的完成优化.
利用贝塞尔曲线重绘
新建一个UIImage的category 并实现如下方法,即可完成图片的裁剪:
//
// UIImage+Extension.m
// 圆角图标
//
// Created by James on 16/3/24.
// Copyright © 2016年 Apple. All rights reserved.
//
#import "UIImage+Extension.h"
@implementation UIImage (Extension)
- (UIImage *)LJ_cornerImageWithSize:(CGSize)size {
//利用绘图,建立上下文
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
CGRect rect = CGRectMake(0, 0, size.width , size.height);
//利用贝塞尔路径裁切效果
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];
[path addClip];
//绘制图像
[self drawInRect:rect];
//取得结果
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
return resultImage;
}
@end
在控制器中这样调用
//
// ViewController.m
// TableView的优化
//
// Created by James on 16/3/24.
// Copyright © 2016年 Apple. All rights reserved.
//
#import "ViewController.h"
#import "UIImage+Extension.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//新建一个redView
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
//设置imageView的image并居中
UIImage *image = [[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"avatar" ofType:@"jpg"]];
imageView.center = self.view.center;
//添加到父控件上
[self.view addSubview:imageView];
//设置圆角
image = [image LJ_cornerImageWithSize:CGSizeMake(200, 200)];
imageView.image = image;
}
@end
效果图如下:
这样基本就完成了,但还是有些小瑕疵,比如黑色部分是需要指定的填充色,而且,这是耗时操作,需要放到子线程中操作,在主线程进行回调即可
//
// UIImage+Extension.m
// 圆角图标
//
// Created by James on 16/3/24.
// Copyright © 2016年 Apple. All rights reserved.
//
#import "UIImage+Extension.h"
@implementation UIImage (Extension)
- (void)LJ_cornerImageWithSize:(CGSize)size fillColor:(UIColor *)fillColor finishedBlock:(void (^)(UIImage *))finished {
//子线程中进行耗时操作
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//利用绘图,建立上下文
UIGraphicsBeginImageContextWithOptions(size, YES, 0);
CGRect rect = CGRectMake(0, 0, size.width , size.height);
//设置填充色
[fillColor setFill];
UIRectFill(rect);
//利用贝塞尔路径裁切效果
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect];
[path addClip];
//绘制图像
[self drawInRect:rect];
//取得结果
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext();
//关闭上下文
UIGraphicsEndImageContext();
//回主线程完成回调
dispatch_async(dispatch_get_main_queue(), ^{
if (finished) {
finished(resultImage);
}
});
});
}
@end
控制器的调用方法
//
// ViewController.m
// 圆角图标
//
// Created by James on 16/3/24.
// Copyright © 2016年 Apple. All rights reserved.
//
#import "ViewController.h"
#import "UIImage+Extension.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//新建一个redView
UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 200, 200)];
//设置imageView的image并居中
UIImage *image = [[UIImage alloc]initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"avatar" ofType:@"jpg"]];
imageView.center = self.view.center;
//添加到父控件上
[self.view addSubview:imageView];
//设置圆角
[image LJ_cornerImageWithSize:CGSizeMake(imageView.bounds.size.width, imageView.bounds.size.height) fillColor:[UIColor whiteColor] finishedBlock:^(UIImage *finishedImage) {
imageView.image = finishedImage;
}];
}
@end
效果图如下:
至此,设置圆角结束