使用SwiftUI在多个iOS设备上显示尺寸准确的标尺图像

问题描述

我正在寻找一种以英寸或毫米而不是点或像素为单位定义图像尺寸的方法。我想在白色背景上显示尺子的图像。无论使用哪种设备(例如iPad air,iPad pro,iPhone se,iPhone 11,iPhone 11 pro等),我都希望屏幕上的图像在用物理标尺测量时能保持一致的尺寸。

我看到了针对每个设备创建单独图像的解决方案,但是我很高兴发现一种可以在所有iOS设备上缩放单个图像大小的方法

如果我的任何一种语言是错误的或令人困惑的,请随时指出/要求澄清。我是一个渴望评论的绿色开发者。

解决方法

总的来说,这比应该做的难。 Apple不需要您为特定设备设计接口,但是对于此应用程序,您必须知道运行的特定设备,以便可以查找该设备的每英寸点数。当我说查找时,您需要提供自己的表(字典),该表将设备名称映射到每英寸点数

第一件事。您如何获得设备名称?

您可以通过致电:

UIDevice.current.name

要查找各种设备返回的信息,请运行以下命令:

struct ContentView: View {

    var body: some View {
        HStack {
            Text(UIDevice.current.name)
        }
    }
}

在各种设备模拟器上发现它们返回的内容。最新的一些是"iPhone 11 Pro Max""iPhone 11 Pro""iPhone 11""iPad Pro (12.9-inch) (4th generation)"

在SwiftUI中,当您指定帧大小时,您是在中工作,而不是在 pixels 中工作。因此,您需要了解所有设备的每英寸点数

This table包含有关许多设备及其分辨率和点尺寸的大量信息。通过一些工作,您可以得出各种设备的每英寸点数。在大多数情况下,每英寸点数只是每英寸像素数除以图像资产乘数(@2x@3x)。 5.5英寸iPhone(6S +,7 +,7S +,8 +)的例外是,它们的分辨率不如应有的那么高,因此其中还有一个额外的1.15比例因子。

一旦您有了每英寸点数,我建议创建一个字典映射设备名称为每英寸点数

let pointsPerInch: [String : CGFloat] = [
    "iPhone 8": 163,// 326 ppi / 2
    "iPhone 8 Plus": 153.716,// 401 ppi * 1.15 / 3
    "iPhone 11": 163,// 326 ppi / 2
    "iPhone 11 Pro": 152.66,// 458 ppi / 3
    "iPhone 11 Pro Max": 152.66,// 458 ppi / 3
    "iPad Pro (12.9-inch) (4th generation)": 132   // 264 ppi / 2
]

最后,您将获得一些标尺的图像。您需要在图像资源中提供这些图像的@ 2x和@ 3x版本。我建议对@ 2x图像使用326 ppi,对@ 3x图像使用458 ppi。 iOS会自动加载适合您设备的@ 2x或@ 3x版本。

在您的应用中,您需要查找设备名称,然后使用词典查找每英寸的点数。然后,将每英寸的点数乘以将要显示的图像的大小(例如,一个12英寸的标尺将是每英寸的点数* 12)。这将为您提供点尺寸,以用于图像的帧尺寸。