CALayers中的iOS绘图drawInContext在视网膜上是像素化的或模糊的

时间:2014-09-09 13:49:02

标签: ios core-graphics calayer retina

我有一个自定义UIView,可以覆盖

- (void)drawRect:(CGRect)rect

这可以很好地工作,并在视网膜屏幕上产生清晰的效果。

但是,现在我想使绘图所基于的属性具有动画效果。创建动画属性似乎只能在CALayer上进行,因此我不是在UIView中进行绘制,而是创建自定义CALayer子类并在里面进行绘制

- (void) drawInContext:(CGContextRef)ctx

我在此函数中使用与自定义drawRect的{​​{1}}函数中使用的完全相同的绘图代码。

结果看起来一样 - 但是,它不是视网膜分辨率而是像素化(大方形像素)

如果我把

UIView

到我的self.contentsScale = [UIScreen mainScreen].scale; 实现的开始,然后我得到一个模糊的结果(好像渲染仍然以非视网膜分辨率执行,然后升级到视网膜分辨率)而不是像素化结果。

drawInContext CALayers中呈现清晰视网膜路径的正确方法是什么?

这里有一些截图(蓝线是有问题的自定义绘图的一部分。黄色部分只是一个图像)

在自定义UIView drawInContext中绘制:

enter image description here

在自定义CALayer drawRect中绘制:

enter image description here

在自定义CALayer的drawInContext内绘图,首先设置drawInContext

enter image description here

为了完整性,这里(图片的精简版)绘图代码:

self.contentScale

重申我想要实现的目标:我希望实现与//if drawing inside custom UIView sublcass: - (void)drawRect:(CGRect)rect { CGContextRef currenctContext = UIGraphicsGetCurrentContext(); [[UIColor blackColor] set]; CGContextSetLineWidth(currenctContext, _lineWidth); CGContextSetLineJoin(currenctContext,kCGLineJoinRound); CGContextMoveToPoint(currenctContext,x1, y1); CGContextAddLineToPoint(currenctContext,x2, y2); CGContextStrokePath(currenctContext); } //if drawing inside custom CALayer subclass: - (void) drawInContext:(CGContextRef)ctx { { //self.contentsScale = [UIScreen mainScreen].scale; CGContextRef currenctContext = ctx; CGContextSetStrokeColorWithColor(currenctContext, [UIColor blackColor].CGColor); CGContextSetLineWidth(currenctContext, _lineWidth); CGContextSetLineJoin(currenctContext,kCGLineJoinRound); CGContextMoveToPoint(currenctContext,x1, y1); CGContextAddLineToPoint(currenctContext,x2, y2); CGContextStrokePath(currenctContext); } 方法相同的清晰视网膜渲染,但在UIView中进行渲染时

3 个答案:

答案 0 :(得分:10)

这个问题最有可能是contentScale;请注意,如果您通过覆盖其layerClass功能将其分配给自定义视图,则可以重置图层的内容比例。可能还有其他一些情况也会发生这种情况。为安全起见,请仅在将图层添加到视图后设置内容比例。

尝试在自定义视图的init方法中将主屏幕的比例分配给自定义图层。在Swift 3中看起来像这样:

layer.contentsScale = UIScreen.mainScreen().scale

或者,在Swift 4中:

layer.contentsScale = UIScreen.main.scale

答案 1 :(得分:9)

您在图层中使用shouldRasterize = YES吗?尝试在CALayer子类中绘图,但将rasterizationScale设置为屏幕的比例。

答案 2 :(得分:3)

将图层添加到其超级图层后。将shouldRasterize设置为YES,将contentsScale和resterizatioinScale设置为屏幕比例:

[self.progressView.layer addSublayer:self.progressLayer];
self.progressLayer.shouldRasterize = YES;
self.progressLayer.contentsScale = kScreenScale;
self.progressLayer.rasterizationScale = kScreenScale;

CABasicAnimation *animate = [CABasicAnimation animationWithKeyPath:@"progress"];// progress is a customized property of progressLayer
animate.duration = 1.5;
animate.beginTime = 0;
animate.fromValue = @0;
animate.toValue = @1;
animate.fillMode = kCAFillModeForwards;
animate.removedOnCompletion = NO;
animate.repeatCount = HUGE_VALF;
[self.progressLayer addAnimation:animate forKey:@"progressAnimation"];