iOS绘图出现的错误
2016-09-09 本文已影响5567人
Lycho
今天使用贝塞尔曲线运行后出现无效上下文错误,这里记录一下。
先上代码:
-(void)createCircle
{
CGPoint layerCenter = CGPointMake(CGRectGetWidth(self.view.frame)/2, CGRectGetWidth(self.view.frame)/2);
CAShapeLayer *layer = [CAShapeLayer layer];
layer.frame = self.view.bounds;
layer.lineWidth = 6.0;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor whiteColor].CGColor;
self.path = [UIBezierPath bezierPath];
[self.path addArcWithCenter:layerCenter radius:50 startAngle:0.0 endAngle:M_PI*2 clockwise:YES];
[self.path stroke];
[self.path fill];
layer.path = self.path.CGPath;
[self.view.layer addSublayer:layer];
}
错误日志如下:
Sep 9 16:09:01 Test1[28072] <Error>: CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextSetLineWidth: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextSetLineJoin: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextSetLineCap: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextSetMiterLimit: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextSetFlatness: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextAddPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextDrawPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextSetFlatness: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextAddPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextDrawPath: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
Sep 9 16:09:01 Test1[28072] <Error>: CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
上网查找错误的原因,大部分都说是IOS9适配问题,设置app的状态栏样式的使用使用了旧的方式在IOS9中不兼容。但是我的工程中并没有设置状态栏,并且按照其解决方法更改后也没有解决这个问题。后来看到这篇文章H含金量 iOS绘图及贝塞尔曲线关键知识才知道问题所在。
因为绘图不在drawRect:方法中操作导致绘图时没有当前的图形上下文(context)可设置。所以应该在drawRect:中执行图形绘制。修改后代码如下:
-(void)createCircle
{
CGPoint layerCenter = CGPointMake(CGRectGetWidth(self.view.frame)/2, CGRectGetWidth(self.view.frame)/2);
CAShapeLayer *layer = [CAShapeLayer layer];
layer.frame = self.view.bounds;
layer.lineWidth = 6.0;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor whiteColor].CGColor;
self.path = [UIBezierPath bezierPath];
[self.path addArcWithCenter:layerCenter radius:50 startAngle:0.0 endAngle:M_PI*2 clockwise:YES];
// [self.path stroke];
// [self.path fill];
layer.path = self.path.CGPath;
[self.view.layer addSublayer:layer];
[self.view setNeedsDisplay];
}
- (void) drawRect:(CGRect)rect {
[self.path stroke];
[self.path fill];
}
或者改成这样:
-(void)createCircle
{
CGPoint layerCenter = CGPointMake(CGRectGetWidth(self.view.frame)/2, CGRectGetWidth(self.view.frame)/2);
CAShapeLayer *layer = [CAShapeLayer layer];
layer.frame = self.view.bounds;
layer.lineWidth = 6.0;
layer.strokeColor = [UIColor redColor].CGColor;
layer.fillColor = [UIColor whiteColor].CGColor;
self.path = [UIBezierPath bezierPath];
[self.path addArcWithCenter:layerCenter radius:50 startAngle:0.0 endAngle:M_PI*2 clockwise:YES];
layer.path = self.path.CGPath;
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.path stroke];
[self.path fill];
UIGraphicsEndImageContext();
[self.view.layer addSublayer:layer];
}
这样就不会再出现错误了。其实我这里的path是UIBezierPath,可以直接去掉[self.path stroke];和[self.path fill];这两处的。