在drawRect方法中绘制大量的线条数据时,会出现卡顿xianxiang。无论是通过异步去移动UIBezerPath还是适当的优化数据量都无法解决[path stroke]花费的时间。
经过测试通过layer的异步绘制可以方便的实现功能。
注意:
_layer.drawsAsynchronously = YES;实现异步绘制
_layer.contentsScale = [UIScreen mainScreen].scale;防止模糊
_layer的代理不能是UIView,如果在view中添加的layer设置代理,可以定义一个中间对象作为代理
在代理方法
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
中用UIGraphicPush(),和UIGraphicPop可以将CGContextRef上下文引用压入当前方法中,这样就可以像drawRect方法一样直接进行绘制工作了。
@interface ViewController ()<CALayerDelegate>
@property (nonatomic, strong) UIBezierPath *path;
@property (nonatomic, strong) CALayer *layer;
@property (nonatomic, strong) NSArray *array;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_layer = [CALayer layer];
_layer.delegate = self;
_layer.drawsAsynchronously = YES;
_layer.frame = self.view.bounds;
_layer.contentsScale = [UIScreen mainScreen].scale;
[self.view.layer addSublayer:_layer];
[NSTimer scheduledTimerWithTimeInterval:1 repeats:YES block:^(NSTimer * _Nonnull timer) {
[self setModels:self.array];
}];
}
- (NSArray *)array {
if (!_array) {
NSInteger count = 20000;
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:count];
for (NSInteger i = 0; i < count; i++) {
Model *model = [[Model alloc] init];
model.x = [UIScreen mainScreen].bounds.size.width / count * i;
model.y = arc4random() % 400 + 50;
[arr addObject:model];
};
_array = [arr copy];
}
return _array;
}
- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx {
if (_path && !_path.isEmpty) {
NSLog(@"开始绘制==");
CGContextSetStrokeColorWithColor(ctx, [UIColor redColor].CGColor);
CGContextSetLineWidth(ctx, 1);
CGContextAddPath(ctx, _path.CGPath);
CGContextStrokePath(ctx);
NSLog(@"结束绘制");
}
}
- (void)setModels:(NSArray *)models {
NSLog(@"设置了model");
_path = [UIBezierPath bezierPath];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
for (NSInteger i = 0; i < models.count; i++) {
Model *mod = [models objectAtIndex:i];
if (i == 0) {
[self.path moveToPoint:CGPointMake(mod.x, mod.y)];
}
else {
[self.path addLineToPoint:CGPointMake(mod.x, mod.y)];
}
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.layer setNeedsDisplay];
});
});
}
- (void)dealloc {
self.layer.delegate = nil;
}
网友评论