如果今年出去面试的话一个非常有意思的"话题"是问你为什么微信头像是方的 而 qq 头像是圆的~,而由此引发的一系列关于头像的方角与圆角的问题......就像哔哩哔哩的弹幕一样......
更多注释和讲解内容请看代码详细信息~
- 在以前的 App客户端中,头像几乎清一色的都是方形,最近这些日子,也不知道谁出的这道题,让我好一阵想~
这个问题的根源其实是你在切圆角的时候如果 tableView 每次滑动的时候你都从复用池拿出来之前再从新切图的话会非常耗费程序性能划着划着就会发现程序变慢了 - 怎么解决呢?!那就是......我了解到的目前有这么一种通过绘制上下文,修改你传过来的图片尺寸的方法~
下面分享给大家~
主Bundle 栏
注意 : " 图层混合 " 的概念
- 如果有透明色会变红的图层会混合y影响性能~
-
无图层混合(绿色)
-
有图层混合(红色)
-
无图层混合(绿色)
UIImage+Extension.h 文件-->( 给 UIImage 添加分类 )
#import <UIKit/UIKit.h>
@interface UIImage (Extension)
//根据当前图像和指定的尺寸,生成圆角并返回圆角图像:
- (void)MD_imageWithSize:(CGSize)size fillColor:(UIColor *)fillColor completion:(void(^) (UIImage *resultImage))completion ;
@end
UIImage+Extension
#import "UIImage+Extension.h"
@implementation UIImage (Extension)
/*
* 如何回调参数 ?
在 iOS 开发中, block 用处最多的用途就是在异步执行完成之后,通过参数回调,通知调用方回调结果!
*/
- (void)MD_imageWithSize:(CGSize)size fillColor:(UIColor *)fillColor completion:(void (^)(UIImage *))completion {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//测试性能:
NSTimeInterval start = CACurrentMediaTime() ;
/*
* 贝塞尔曲线画圆:
*/
//1.开启绘图上下文
UIGraphicsBeginImageContextWithOptions(size, YES, 0) ;
CGRect rect = CGRectMake(0, 0, size.width, size.height) ;
//2.设置填充颜色:
[fillColor setFill] ;
//光有填充颜色不够还要做一个填充:
UIRectFill(rect) ;
//3.贝塞尔曲线画圆:
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect] ;
[path addClip] ;//裁切
//4.绘制图像:
[self drawInRect:rect] ;//绘图
//5.取得上下文会治好的图片:
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext() ;//取得当前绘制完成后的图片
//6结束上下文:
UIGraphicsEndImageContext() ;//结束绘制上下文
//性能测试:看执行这段代码需要多长时间:
NSLog(@"%f" , CACurrentMediaTime() - start) ;
//大概在0.01s 以内,既然如此发现他还是比较浪费时间的~那我恩么办呢?!~~~多线程呗!!!
//完成回调参数:
dispatch_async(dispatch_get_main_queue(), ^{
//这里要判断一下是否有参数回调到回来,如果不判断会崩溃的!
if (completion != nil) {
completion(resultImage) ;
}
}) ;
}) ;
}
@end
ViewController.m 文件
#import "ViewController.h"
#import "UIImage+Extension.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)] ;
imageView.backgroundColor = [UIColor clearColor] ;
imageView.center = self.view.center ;
[self.view addSubview:imageView] ;
//设置图像:
//创建对象:
UIImage *image = [UIImage imageNamed:@"avatar"] ;
//给 UIImage 添加分类方法(对象方法 - ):
[image MD_imageWithSize:imageView.bounds.size fillColor:[UIColor whiteColor] completion:^(UIImage *resultImage) {
//把 image 进过 MD_imageWithSize:(CGSize) fillColor:(UIColor *) completion:^(UIImage *resultImage) {...} 操作之后image 变成了 resultImage, 再把这个 resultImage 回调回来传递给我创建的 imageView的 image 属性.让 resultImage 称为这个图像(imageView)的图片(image)!
imageView.image = resultImage ;
}] ;
}
//color blended layers = 混合图层 ;
//使用颜色不能带透明度,使用带透明度的颜色会严总影响性能!!!在开发中不到万不得已千万别这么做!
//模拟器这个呢的 blended 混合模式 , 说明是做过透明处理的.
//在模拟器的界面中如果遇到这个红色的混合图层情况,除了 UILabel 我们可以不用管,其他的尽量都要处理掉!
//UILabel 内部的封装较差,为了解决这个问题,有一些框架会自己创建 UILabel,比如 YYText,他就觉得系统的 UILabel 不好~的确如此,在苹果的各个控件里 UILabel 的性能就是很差劲!
@end