Xcode 11 PDF 图像资产“保留矢量数据”在 SwiftUI 中不起作用?

Posted

技术标签:

【中文标题】Xcode 11 PDF 图像资产“保留矢量数据”在 SwiftUI 中不起作用?【英文标题】:Xcode 11 PDF image assets "Preserve Vector Data" not working in SwiftUI? 【发布时间】:2019-09-17 08:00:06 【问题描述】:

我正在尝试在 Xcode 11 中使用 SwiftUI 的应用程序中使用“单比例”的基于矢量的 PDF 图像,但是当我放大图像时,图像总是看起来模糊。

我在 Xcode 11 的 UIKit 中对此没有任何问题。我创建了一个具有 2 个场景的虚拟应用程序,它们都显示相同的矢量图像。我在情节提要中创建了第一个场景,然后使用 HostingViewController 嵌入了在 SwiftUI 中制作的相同场景。当我运行应用程序时,第一个场景 (UIKit) 显示了一个清晰、不模糊的图像。然而,第二个 (SwiftUI) 场景很模糊,并且似乎没有使用矢量数据,尽管使用了相同的源图像资源。

我能够通过使用矢量图像创建一个 UIImage 来“解决”这个问题,然后使用这个 UIImage 扩展来调整 UIImage 的大小,然后再将它传递给Image。但是,我在 resized(to:) 方法中输入的大小在运行时没有任何区别,因此我还必须在 'var body' 中将 .frame(w:,h:) 添加到 image 以使其显示正确的大小。

let uiImage = UIImage(named: "Logo-vector")!
var image: Image 
        Image(uiImage: uiImage.resized(to: CGSize(width: 500, height: 500)))
            .resizable()


var body: some View 
        NavigationView 
            VStack(alignment: .center, spacing: 8) 
                Spacer()
                Text("Logo vector SwiftUI")
                image
                    .frame(width: 240, height: 216)
                ...
                
                ...
            
        


extension UIImage 
    func resized(to size: CGSize) -> UIImage 
        return UIGraphicsImageRenderer(size: size).image  _ in
            draw(in: CGRect(origin: .zero, size: size))
        
    

使用此解决方法,图像清晰且在运行时正确调整大小,但感觉有点像 hack。

我在网上到处寻找不同的解决方案或其他任何人专门使用 SwiftUI 遇到此问题,但根本没有找到任何东西。

有没有其他人遇到过这个问题或者有没有更好的解决方案?

【问题讨论】:

是的,你的技巧对我有用。但我不明白为什么我在 Assets.xcasstets 中使用的这个停止工作总是 PDF +“保留矢量图形”+“单比例”并且它有效。在 Xcode 11.3.1、ios 13.x 中,它似乎无法正常工作。也许它与 SwiftUI 中的视图刷新有关,因为刷新处理存在很多问题 @MichałZiobro 我不使用 SwiftUI,它也坏了。 你有没有想过这个问题?在小部件中使用图像时,在 Xcode 12 beta 1 中看到相同的行为。 这能回答你的问题吗? Why do PDFs resized in SwiftUI getting sharp edges? 【参考方案1】:

尝试在每个 pdf 图像资产上启用“IPreserve 矢量数据” (在“Assets.xcassets”文件夹中选择图像,然后在“属性检查器>图像集>调整大小”中)

【讨论】:

【参考方案2】:

这对我有用。无需在开始时声明 image 变量

NavigationView 
      VStack(alignment: .center, spacing: 8) 
      Spacer()
      Text("Logo vector SwiftUI")

      Image(systemName: "text.bubble") // or Image("ImageName") for local assets
          .resizable().aspectRatio(contentMode: .fit)
          .frame(width:100, height:100)


            
            ...
        

【讨论】:

将您的图像添加到 Assets.xcassets 文件夹。确保 Assets.xcassets 中的图像名称匹配。例如。如果你有一个名为 hello_world.png 的图像,在你的 SwiftUI 代码中它应该是 Image("hello_world")【参考方案3】:

我整合了一个名为 ResizableVector 的跨平台框架,它执行相同的大小调整方法。

extension PlatformImage 
    func resized(to size: CGSize) -> PlatformImage 
        return GraphicsImageRenderer(size: size).image  _ in
            self.draw(in: CGRect(origin: .zero, size: size))
        
    

其中 PlatformImage 只是 UIImage 或 NSImage 的类型别名,GraphicsImageRenderer 是 UIGraphicsImageRenderer 或 MacGraphicsImageRenderer 的类型别名。

框架提供了一个名为 ResizableVector 的 SwiftUI 视图来代替 Image。如果需要,它还可以尊重原始纵横比。

您可以使用 SPM 添加它 - 在 GitHub 上查看: https://github.com/Matt54/ResizableVector

【讨论】:

以上是关于Xcode 11 PDF 图像资产“保留矢量数据”在 SwiftUI 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Xcode 中的 pdf 资产上设置色调颜色?

如何将 PSD 文件中的所有图层导出为 PDF 矢量以在 Xcode 6 中使用资产目录

使用 Xcode 10 在 Watch Simulator 中未显示资产目录图像?

Xcode 在条形按钮项目大小太大时使用 PDF 图像

如何在资产目录中设置可访问性标签? Xcode 11

Xcode 中的 PDF 图标模糊