前言:

最近面试,有许多公司都会问这么一个问题:说说你怎么设置圆角图标的(不要说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

ios圆角优化 ios圆角图标_圆角


虽然这种方法很简单,但却是以牺牲性能为代价的,如果在tableView中使用这种方法设置头像,会导致cell在每次重用的时候都重新计算图片尺寸并进行切割,浪费过多的系统资源,导致每次滑动tableView的时候造成卡顿,影响用户体验.检验:利用模拟器中的Debug中的ColorMisaligned Images选项,可以看到下图效果:

ios圆角优化 ios圆角图标_#import_02


说明在显示时,图片大小与容器大小不符,被拉伸过.

利用Debug中的Color Blended Layers 可以看到那些红色部分,就是造成浪费资源浪费的罪魁祸首,他们是透明的layer

ios圆角优化 ios圆角图标_#import_03


我们就是要把这些没有必要是透明的部分解决掉,快速的完成优化.

利用贝塞尔曲线重绘

新建一个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

效果图如下:

ios圆角优化 ios圆角图标_优化_04


这样基本就完成了,但还是有些小瑕疵,比如黑色部分是需要指定的填充色,而且,这是耗时操作,需要放到子线程中操作,在主线程进行回调即可

//
//  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

效果图如下:

ios圆角优化 ios圆角图标_面试_05


至此,设置圆角结束