-drawRect方法绘制卡顿,通过CALayer绘制解决

在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;
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,613评论 6 30
  • 1 CALayer IOS SDK详解之CALayer(一) http://doc.okbase.net/Hell...
    Kevin_Junbaozi阅读 5,230评论 3 23
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,164评论 5 13
  • 转载:http://www.jianshu.com/p/32fcadd12108 每个UIView有一个伙伴称为l...
    F麦子阅读 6,403评论 0 13
  • 人在国外,这次第三第四次作业比较仓促,老师同学多见谅。 在你的行业里面,选择一家规模化扩张的公司,分析它的发展路径...
    roger爸阅读 258评论 0 0