iOS:如何使用CGLayer支持Retina显示?

19

我正在CALayer的委托方法drawLayer:inContext:中绘制图形。

现在我想支持Retina显示屏,因为在最新的设备上,图形看起来很模糊。

对于我直接在CALayer传递的图形上绘制的部分,可以通过设置CALayer的contentScale属性来高分辨率绘制。

if ([myLayer respondsToSelector:@selector(setContentsScale:)]) {
    myLayer.contentsScale = [[UIScreen mainScreen] scale];
}

但我使用CGLayer的部分仍然模糊。

如何在高分辨率下绘制CGLayer以支持Retina显示?

我想使用CGLayer重复绘制相同的图形,以及裁剪超出层边缘的图形线条。

我通过CALayer传递的图形上下文调用CGLayerCreateWithContex来获取CGLayer,并使用CG函数例如CGContextFillPathCGContextAddLineToPoint来绘制其上下文。

我需要同时支持iOS 4.x和iOS 3.1.3,以及Retina和旧版显示器。

谢谢,

Kura


1
看起来这篇文章可能与此相关: https://dev59.com/I1HTa4cB1Zd3GeqPOAhd - Duncan Babbage
Duncan,感谢您的评论,但不是这样的...我之前已经阅读过这篇文章,但它是关于直接在UIView上下文中绘制的。CALayer与UIView具有相同的“scale”属性,并且正如我所述,它可以工作。我的问题是关于在CGLayer上绘制。CGLayer没有“scale”属性。 :( - Taka
2个回答

28

这是如何正确绘制适用于所有分辨率的CGLayer的方法。

  1. 当首次创建图层时,您需要通过将尺寸乘以比例来计算出正确的边界:

    int width = 25; 
    int height = 25;
    float scale = [self contentScaleFactor];
    CGRect bounds = CGRectMake(0, 0, width * scale, height * scale);
    CGLayer layer = CGLayerCreateWithContext(context, bounds.size, NULL);
    CGContextRef layerContext = CGLayerGetContext(layer);
    
    然后您需要为图层上下文设置正确的比例尺:
  2. CGContextScaleCTM(layerContext, scale, scale);
    
  3. 如果当前设备具有Retina显示屏,那么绘制到该图层的所有内容将被放大两倍。

  4. 当最终绘制图层内容时,请确保使用CGContextDrawLayerInRect并提供未缩放的CGRect:

  5. CGRect bounds = CGRectMake(0, 0, width, height);
    CGContextDrawLayerInRect(context, bounds, layerContext);
    

就这样!


谢谢!下次我会试试的。;) - Taka
谢谢您,这正是应该的。 - neevek
这样做可以显著提高清晰度,但仍然比直接使用上下文(不使用CGlayer)绘图略微不够锐利。这是正常的吗?我还尝试将缩放设置为4或8。 - User

1

我决定不使用CGLayer,而是直接在CALayer的图形上下文中绘制,现在在Retina显示屏上以高分辨率绘制得很好。

我在这里找到了类似的问题here,发现在我的情况下使用CGLayer没有意义。

我之前使用CGLayer是因为在Quartz 2D编程指南中发现了苹果的示例程序"Using Multiple CGLayer Objects to Draw a Flag"。在这个例子中,它为一个星形创建了一个CGLayer,并多次使用它来绘制50个星形。我认为这是出于性能考虑,但我没有看到任何性能差异。

为了截断超出图层边缘的图形线条,我决定使用多个CALayer。


这并不是问题的解决方案。这是一个有趣的问题,我希望有一个答案。该链接也没有提供除与苹果文档相矛盾的建议之外的解决方案。 - Hari Honor
1
关于性能:在我的应用程序中,我正在使用UIImage方法drawInRect:。在我测量的一个场景中,使用CGLayer比直接使用CALayer上下文绘制大约快20倍(约50毫秒对比约1秒)。因此,我的猜测是,这可能取决于存储在CGLayer中的绘图操作类型,是否存在性能差异。 - herzbube

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接