使用SVG在iOS应用中实现分辨率独立性

拥有各种尺寸的设备非常适合允许用户选择适合自己的设备,但是支持分辨率和像素密度的所有这些组合可能很麻烦。 即使您以某种矢量格式开发所有原始图稿,通常也必须以各种尺寸和密度将其导出为PNG格式。

如果您的应用程序中只有几个图像,这可能是可管理的,但是随着图像数量的增加,它很快就会变得笨拙而乏味。 另外,如果您有任何全屏(特别是iPad尺寸)图像,则以多个密度包含同一图像的冗余副本将迅速增加应用程序的总体存储空间需求。

另外,您也可以直接在应用程序中使用矢量图像。 此时,Xcode支持的唯一矢量格式是PDF。 您可以将PDF添加到资产管理器,它会按预期显示在Interface Builder中。 但是,在构建应用程序时实际发生的事情是,这些漂亮的矢量图像在编译时就被光栅化了。 因此,在运行时,您仍在处理固定大小的PNG图像。

这意味着您仍然受制于多个冗余映像的空间开销。 而且,如果您的应用在运行时对图像大小执行任何操作,您仍然会注意到一些像素化。 这就是SVG出现的地方。

救援的SVG

如果您还不熟悉SVG,它是一种基于XML的矢量图像格式,这意味着即使与PNG相比,它的文件大小也相对较小。 作为矢量图像,它仅包含用于重绘图像的指令,而不包含实际的图像位图数据。 只需说一句,您只需在应用程序中包含一个SVG副本。 这可以大大减少应用程序的存储需求,并简化应用程序图稿的管理。

由于Xcode不支持SVG,因此您需要找到第三方库才能将SVG支持添加到您的应用中。 我在最新的iOS项目中一直使用的是SVGKit。 它具有一个缓存系统以减少解析SVG文件的开销,并且它使用CoreAnimation层进行渲染以避免大多数性能问题。

使用Interface Builder进行布局

如果要使用Interface Builder设计布局,则可以为SVG添加图像视图,但是直到运行时才能看到图像。 由于Xcode和Interface Builder不直接支持SVG,因此,我们将不得不采用一个小的解决方法。

1.在Interface Builder中,将新的View对象添加到您的界面中(这在可用对象列表的结尾附近)。

2.像往常一样将此新视图约束到其他视图。 使用矢量图像的好处是您可以灵活选择尺寸。 但是,我仍然建议添加与源图像的宽高比匹配的宽高比约束。 这将防止图像因其他约束而失真。

3.将视图的类更改为SVGKFastImageView 。 这不会影响其在设计时的外观,但是当在运行时加载笔尖时,视图将是此类的一个实例。

4.将IBOutlet添加到视图控制器类,并将其连接到在步骤1中添加的视图。

5.用代码将所需图像加载到视图中。 例如:

 请参阅完整文章中的代码。 

使用代码进行布局

如果要通过在代码中构造视图对象来设置界面,则该过程可能与您已经在做的事情有点相符。 这样的事情将为您提供SVG图像视图并将图像加载到其中:

 请参阅完整文章中的代码。 

尽管上面的代码可以工作,没有任何限制,但是图像将根据SVG的内部尺寸进行调整。 因此,您仍然需要添加一些约束来控制图像大小。

如果您要添加更多其他相同的具有不同大小的图像视图,则可以看到图像可以缩放而不会降低质量:

其他提示

如果发现加载SVG图像时布局变得混乱,请尝试使用抗压缩性和内容优先的图像视图。 通常可以将它们设置为1(最小值),以确保图像视图仅从其他约束中获得其大小,而不从其固有大小中获得。

最后,由于我项目中的SVG混合了明暗,大大小小的等等,因此尝试在Finder中预览不是一件容易的事。 因此,我使用以下脚本来生成一个HTML页面,其中包含当前目录中所有SVG图像的预览。 随意使用它,并根据需要对其进行调整!

 请参阅完整文章中的代码。