美文网首页
-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