如果今年出去面試的話一個(gè)非常有意思的"話題"是問(wèn)你為什么微信頭像是方的 而 qq 頭像是圓的~,而由此引發(fā)的一系列關(guān)于頭像的方角與圓角的問(wèn)題......就像嗶哩嗶哩的彈幕一樣......
更多注釋和講解內(nèi)容請(qǐng)看代碼詳細(xì)信息~
- 在以前的 App客戶(hù)端中,頭像幾乎清一色的都是方形,最近這些日子,也不知道誰(shuí)出的這道題,讓我好一陣想~
這個(gè)問(wèn)題的根源其實(shí)是你在切圓角的時(shí)候如果 tableView 每次滑動(dòng)的時(shí)候你都從復(fù)用池拿出來(lái)之前再?gòu)男虑袌D的話會(huì)非常耗費(fèi)程序性能劃著劃著就會(huì)發(fā)現(xiàn)程序變慢了 - 怎么解決呢?!那就是......我了解到的目前有這么一種通過(guò)繪制上下文,修改你傳過(guò)來(lái)的圖片尺寸的方法~
下面分享給大家~
主Bundle 欄

Snip20161218_9.png
注意 : " 圖層混合 " 的概念
- 如果有透明色會(huì)變紅的圖層會(huì)混合y影響性能~
-
無(wú)圖層混合(綠色)
Snip20161218_10.png -
有圖層混合(紅色)
Paste_Image.png
-
無(wú)圖層混合(綠色)
UIImage+Extension.h 文件-->( 給 UIImage 添加分類(lèi) )
#import <UIKit/UIKit.h>
@interface UIImage (Extension)
//根據(jù)當(dāng)前圖像和指定的尺寸,生成圓角并返回圓角圖像:
- (void)MD_imageWithSize:(CGSize)size fillColor:(UIColor *)fillColor completion:(void(^) (UIImage *resultImage))completion ;
@end
UIImage+Extension
#import "UIImage+Extension.h"
@implementation UIImage (Extension)
/*
* 如何回調(diào)參數(shù) ?
在 iOS 開(kāi)發(fā)中, block 用處最多的用途就是在異步執(zhí)行完成之后,通過(guò)參數(shù)回調(diào),通知調(diào)用方回調(diào)結(jié)果!
*/
- (void)MD_imageWithSize:(CGSize)size fillColor:(UIColor *)fillColor completion:(void (^)(UIImage *))completion {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//測(cè)試性能:
NSTimeInterval start = CACurrentMediaTime() ;
/*
* 貝塞爾曲線畫(huà)圓:
*/
//1.開(kāi)啟繪圖上下文
UIGraphicsBeginImageContextWithOptions(size, YES, 0) ;
CGRect rect = CGRectMake(0, 0, size.width, size.height) ;
//2.設(shè)置填充顏色:
[fillColor setFill] ;
//光有填充顏色不夠還要做一個(gè)填充:
UIRectFill(rect) ;
//3.貝塞爾曲線畫(huà)圓:
UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:rect] ;
[path addClip] ;//裁切
//4.繪制圖像:
[self drawInRect:rect] ;//繪圖
//5.取得上下文會(huì)治好的圖片:
UIImage *resultImage = UIGraphicsGetImageFromCurrentImageContext() ;//取得當(dāng)前繪制完成后的圖片
//6結(jié)束上下文:
UIGraphicsEndImageContext() ;//結(jié)束繪制上下文
//性能測(cè)試:看執(zhí)行這段代碼需要多長(zhǎng)時(shí)間:
NSLog(@"%f" , CACurrentMediaTime() - start) ;
//大概在0.01s 以?xún)?nèi),既然如此發(fā)現(xiàn)他還是比較浪費(fèi)時(shí)間的~那我恩么辦呢?!~~~多線程唄!!!
//完成回調(diào)參數(shù):
dispatch_async(dispatch_get_main_queue(), ^{
//這里要判斷一下是否有參數(shù)回調(diào)到回來(lái),如果不判斷會(huì)崩潰的!
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] ;
//設(shè)置圖像:
//創(chuàng)建對(duì)象:
UIImage *image = [UIImage imageNamed:@"avatar"] ;
//給 UIImage 添加分類(lèi)方法(對(duì)象方法 - ):
[image MD_imageWithSize:imageView.bounds.size fillColor:[UIColor whiteColor] completion:^(UIImage *resultImage) {
//把 image 進(jìn)過(guò) MD_imageWithSize:(CGSize) fillColor:(UIColor *) completion:^(UIImage *resultImage) {...} 操作之后image 變成了 resultImage, 再把這個(gè) resultImage 回調(diào)回來(lái)傳遞給我創(chuàng)建的 imageView的 image 屬性.讓 resultImage 稱(chēng)為這個(gè)圖像(imageView)的圖片(image)!
imageView.image = resultImage ;
}] ;
}
//color blended layers = 混合圖層 ;
//使用顏色不能帶透明度,使用帶透明度的顏色會(huì)嚴(yán)總影響性能!!!在開(kāi)發(fā)中不到萬(wàn)不得已千萬(wàn)別這么做!
//模擬器這個(gè)呢的 blended 混合模式 , 說(shuō)明是做過(guò)透明處理的.
//在模擬器的界面中如果遇到這個(gè)紅色的混合圖層情況,除了 UILabel 我們可以不用管,其他的盡量都要處理掉!
//UILabel 內(nèi)部的封裝較差,為了解決這個(gè)問(wèn)題,有一些框架會(huì)自己創(chuàng)建 UILabel,比如 YYText,他就覺(jué)得系統(tǒng)的 UILabel 不好~的確如此,在蘋(píng)果的各個(gè)控件里 UILabel 的性能就是很差勁!
@end

