美文网首页
-drawRect方法绘制卡顿,通过CALayer绘制解决

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

作者: LX2014 | 来源:发表于2018-07-15 09:28 被阅读192次

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

相关文章

网友评论

      本文标题:-drawRect方法绘制卡顿,通过CALayer绘制解决

      本文链接:https://www.haomeiwen.com/subject/oltpuftx.html