【问题标题】:SPM and images in Storyboard故事板中的 SPM 和图像
【发布时间】:2021-06-28 11:08:56
【问题描述】:

我在开发项目时遇到问题。我决定改用 SPM,几乎一切都按预期工作,但我一直在与一件事作斗争,我不知道我应该这样做。

我有几个包裹。其中之一是 UI 包,其中包含一些图像、一些可重用屏幕的自定义实现等,但最重要的是它包含一些在其他包周围使用的图标。

我有第二个包,它涵盖了我的应用程序的一部分的实现。在这里我们可以找到所有与此功能相关的屏幕,并且它内部还有一些故事板(将来我会将此故事板重写为代码版本)。我有一个问题 - 因为情节提要在运行时无法从其他包加载图像,所以即使在 Xcode 中我可以看到情节提要有一个图像并且这个图像来自其他包,在运行时它不会加载。当我为此使用 Pods 时,我有一个小脚本在 Assets 文件夹表单 UI 框架到 FunctionalityFramework 之间创建引用,并且在此操作之后图像被正确加载(类似于那里描述的:Storyboard, UIImageView. Load image from bundle

但是我如何通过 SPM 实现这一目标?我无法在两个包及其文件夹之间进行引用。有什么方法可以实现吗?

【问题讨论】:

    标签: ios swift xcode storyboard swift-package-manager


    【解决方案1】:

    Swift 5.3 为提供的资源增加了对 SPM 的改进,因此完成您所要求的一种方法是让您的 swift 包出售图像,然后通过支持 Storyboard 视图的UIViewController 加载这些图像。

    可以在here 找到 Apple 的捆绑资源文档。

    以下是重点:

    确保您的 swift 包具有为目标声明的资源:

    targets: [
        .target(
            name: "MyLibrary",
            resources: [
                .process("Resources")
                // This will process the /Sources/MyLibrary/Resources directory.
            ]
        ),
    ]
    

    当资源被声明时,一个新的Bundle 引用变为可用,它引用了包资源。 Bundle.module 引用可用于加载和提供图像。在您的 swift 包中,您可以指定可用的图像,例如:

    #if canImport(UIKit)
    import UIKit
    
    public extension UIImage {
        static var myImage: UIImage? = UIImage(named: "ImageName", bundle: Bundle.module, compatibleWith: nil)
    }
    #endif
    

    现在,在您的UIViewController 中,您应该可以导入您的包,并将图像分配给@IBOutlet

    import UIKit
    import MyLibrary
    
    class ViewController: UIViewController {
        
        @IBOutlet var imageView: UIImageView!
        
        func viewDidLoad() {
            super.viewDidLoad
            imageView.image = .myImage
        }
    }
    

    另一种方法是通过您的库提供自定义UIImageView 类,该类将从Bundle.module 加载图像。这可以通过 Storyboard 来实现,但您将失去在原地查看图像的能力。例如,如果我在我的 swift 包中声明了这个类:

    public class AppIconImageView: UIImageView {
        @IBInspectable var imageName: String = "" {
            didSet {
                image = UIImage(named: imageName, in: Bundle.module, compatibleWith: nil)
            }
        }
    }
    

    然后我可以在 Storyboard 中使用该类。通过imageName 运行时属性提供要显示的图像的名称。 (然后您可以在 Interface Builder 中取消设置“图像”设置。)

    就像我提到的,图像不会显示在故事板中(@IBDesignable 在其他模块中通常很棘手),但在运行时,包资源应该加载。

    【讨论】:

    • 不是真的 :) 我知道,通过代码我可以从不同的捆绑包中加载图像 - 问题是是否有可能将图像从其他捆绑包直接加载到情节提要中,因为您的解决方案(和一个我'已经尝试过)迫使我花费大量时间来更新所有故事板(我知道,最好的选择是将它们重写为代码库,但这是一个收购项目:))换句话说 - 我如何强制故事板加载所有可在 Xcode 故事板编辑器中访问的图像 :)
    • @KamilWalas 明白了。我添加了一种额外的方法,可以让你通过故事板做你想做的事,但有一些设计限制。
    • 是的,我会采用这个解决方案,但我认为有机会在不进行此更改的情况下加载图像。非常感谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-05
    • 1970-01-01
    • 1970-01-01
    • 2016-10-30
    • 2017-11-27
    • 1970-01-01
    相关资源
    最近更新 更多