与 CATiledLayer 一起使用时,UIView 的“contentScaleFactor”背后的秘密是啥?

Posted

技术标签:

【中文标题】与 CATiledLayer 一起使用时,UIView 的“contentScaleFactor”背后的秘密是啥?【英文标题】:What is the secret behind "contentScaleFactor" of UIView when used with CATiledLayer?与 CATiledLayer 一起使用时,UIView 的“contentScaleFactor”背后的秘密是什么? 【发布时间】:2011-07-13 11:00:36 【问题描述】:

您好,

我正在开发一个受 ios SDK 附带的“ZoomingPDFViewer”示例启发的应用程序。在某个时候,我发现了以下代码:

// to handle the interaction between CATiledLayer and high resolution
// screens, we need to manually set the tiling view's 
// contentScaleFactor to 1.0. (If we omitted this, it would be 2.0 
// on high resolution screens, which would cause the CATiledLayer 
// to ask us for tiles of the wrong scales.)
pageContentView.contentScaleFactor = 1.0;

我试图了解更多关于contentScaleFactor 及其作用的信息。在阅读了所有提到它的 Apple 文档后,我搜索了 Google,但从未找到它实际作用的明确答案。

以下是一些我很好奇的事情:

    在绘制 UIView/CALayer 的内容时,contentScaleFactor 似乎对图形上下文有某种影响。这似乎与高分辨率显示器(如 Retina 显示器)有关。 contentScaleFactor 究竟有什么样的影响?

    当使用UIScrollView 并将其设置为缩放时,比如说我的contentViewcontentView 的所有子视图也在缩放。这是如何运作的? UIScrollView 修改了哪些属性以使视频播放器变得模糊和放大?

TL;DR:UIScrollView 的缩放功能是如何“在后台”工作的?我想了解它是如何工作的,以便编写正确的代码。

非常感谢任何提示和解释! :)

【问题讨论】:

【参考方案1】:

坐标以点而不是像素表示。 contentScaleFactor 定义了点和像素的关系:如果是1,点和像素是一样的,如果是2(就像retina display),就意味着每个点都有两个像素。

在普通绘图中,使用点意味着您不必担心分辨率:在 iphone 3(scaleFactor 1)和 iphone4(scaleFactor 2 和 2x 分辨率)中,您可以使用相同的坐标和绘图代码。但是,如果您正在绘制图像(直接,作为纹理......)并且仅使用法线坐标(点),则您不能相信像素到点的映射是 1 比 1。如果这样做,那么每个像素如果 scaleFactor 为 2(x 方向为 2,y 方向为 2),图像将对应 1 个点但 4 个像素,因此图像可能会变得有点模糊

使用CATiledLayer 时,使用比例因子2 可能会产生一些意想不到的结果。我猜想UIViewcontentScaleFactor==2 层和contentScale==2 层会混淆系统,有时还会使比例倍增。 Scrollview 可能会发生类似的情况。

希望这能澄清一点

【讨论】:

很好的答案,这是最新的摘要和点、比例因子和分辨率paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions【参考方案2】:

Apple 在 iOS 开发文档的“支持高分辨率屏幕”页面上有一个关于此的部分。

页面说:

更新您的自定义绘图代码

当您在应用程序中进行任何自定义绘图时,大多数时候 你不需要关心底层证券的分辨率 屏幕。原生绘图技术自动确保 您在逻辑坐标空间图中正确指定的坐标 到底层屏幕上的像素。但是,有时您可能需要 知道当前的比例因子是什么,以便呈现您的 内容正确。对于这些情况,UIKit、Core Animation 和 其他系统框架为您提供绘图所需的帮助 正确。

以编程方式创建高分辨率位图图像 目前使用 UIGraphicsBeginImageContext 函数创建 位图,您可能需要调整代码以将比例因子纳入 帐户。 UIGraphicsBeginImageContext 函数总是创建 比例因子为 1.0 的图像。如果底层设备有一个 高分辨率屏幕,使用此功能创建的图像可能无法 渲染时看起来很平滑。创建具有比例因子的图像 除了 1.0,使用 UIGraphicsBeginImageContextWithOptions 反而。使用此功能的过程与使用相同 UIGraphicsBeginImageContext 函数:

    调用 UIGraphicsBeginImageContextWithOptions 创建位图 上下文(使用适当的比例因子)并将其推送到 图形堆栈。 使用 UIKit 或 Core Graphics 例程绘制 图片。 调用 UIGraphicsGetImageFromCurrentImageContext 来获取位图的 内容。 调用 UIGraphicsEndImageContext 从堆栈中弹出上下文。

例如下面的代码sn -p 创建一个 200 x 200 像素的位图。 (像素数为 通过将图像的大小乘以比例来确定 因素。)

UIGraphicsBeginImageContextWithOptions(CGSizeMake(100.0,100.0), NO, 2.0);

在这里查看:Supporting High-Resolution Screens

【讨论】:

请注意,将 0.0 作为比例传递会导致 UIGraphicsBeginImageContextWithOptions: 使用设备主屏幕的 contentScaleFactor。在我看来,这是充分利用您所使用的任何分辨率设备的最简单选择。这将自动将 1.0 用于“普通”设备,将 2.0 用于 Retina 设备。很好,很容易!

以上是关于与 CATiledLayer 一起使用时,UIView 的“contentScaleFactor”背后的秘密是啥?的主要内容,如果未能解决你的问题,请参考以下文章

CATiledLayer 在 iPad 第 3 代放大时被移除和刷新

如何使用 UIScrollView 和 CATiledLayer 在可缩放的 UIView 上绘制标记

CATiledLayer 显示以前的图块

CATiledLayer drawLayer:inContext:在检索要绘制的图像时释放视图时崩溃

CATiledLayer 的背景图像

隐藏 CATiledLayer 平铺创建