性能优化之 UI渲染优化 - 异步渲染
使用displayLayer进行异步绘制
UIView 绘制流程图
@interface PWView : UIView
@property (nonatomic,strong) NSString *text;
@property (nonatomic,strong) UIColor *backgColor;
@end
#import "PWView.h"
#import <CoreText/CoreText.h>
@implementation PWView
// layer层的重写
-(void)displayLayer:(CALayer *)layer{
CGSize size = self.bounds.size;
CGFloat scale = [UIScreen mainScreen].scale;
// 异步绘制 切换至子线程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
UIGraphicsBeginImageContextWithOptions(size, NO, scale);
// 获取当前上下文
CGContextRef context = UIGraphicsGetCurrentContext();
// 将坐标系反转
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
// 文本沿着Y轴移动
CGContextTranslateCTM(context, 0, size.height);
// 文本反转成context坐标系
CGContextScaleCTM(context, 1, -1);
// 创建绘制区域
CGMutablePathRef path = CGPathCreateMutable();
CGPathAddRect(path, NULL, CGRectMake(0 , 0, size.width, size.height));
// 背景色
CGContextSetFillColorWithColor(context, self.backgColor.CGColor);
CGContextAddRect(context, CGRectMake(0, 0, size.width * scale, size.height * scale));
CGContextFillPath(context);
// 创建需要绘制的文字
NSMutableAttributedString * attStr = [[NSMutableAttributedString alloc]initWithString:self.text];
// 根据attStr 生产CTFramesetterRef
CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attStr);
CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, attStr.length), path, NULL);
// 将frame的内容绘制到context中
CTFrameDraw(frame, context);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();//结束绘制
dispatch_async(dispatch_get_main_queue(), ^{
self.layer.contents = (__bridge id _Nullable)(image.CGImage);
});
});
}
@end
调用
PWView *view = [[PWView alloc]initWithFrame:CGRectMake(100, 100, 200, 200)];
view.text = @"BBBB";
view.backgColor = [UIColor grayColor];
[self.view addSubview:view];
// 注意 需要调用layer层的setNeedsDisplay才会进行异步绘制
[view.layer setNeedsDisplay];
网友评论