情节提要中的 SPM 和图像
SPM and images in Storyboard
我在开发项目时遇到了问题。我已经决定切换到 SPM,几乎一切都按预期工作,但我一直在为一件事而奋斗,我不知道我应该怎么做。
我有几个包裹。其中之一是 UI 包,其中包含一些图像、一些可重用屏幕的自定义实现等,但最重要的是它包含一些在其他包周围使用的图标。
我有第二个包,它涵盖了我的应用程序的一部分的实现。在这里我们可以找到与这个功能相关的所有屏幕,并且它里面还有一些故事板(以后我会把这个故事板改写成代码版)。我有一个问题——因为故事板无法在运行时从其他包加载图像,所以即使在 Xcode 中我可以看到故事板有图像并且该图像来自其他包,但在运行时它不会加载。当我为此使用 Pods 时,我有一个小脚本在 Assets 文件夹形式 UI 框架与 FunctionalityFramework 之间创建引用,在此操作之后图像正确加载(类似于那里描述的:Storyboard, UIImageView. Load image from bundle)
但是我如何通过 SPM 实现这一目标呢?我无法在两个包及其文件夹之间进行引用。有什么办法可以实现吗?
Swift 5.3 添加了对 SPM 的改进以提供资源,因此完成您所要求的一种方法是让您的 swift 包出售图像,然后通过 UIViewController
支持 Storyboard 视图。
可以找到 Apple 的捆绑资源文档 here。
以下是要点:
确保您的 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
class,它将从 Bundle.module
加载图像。这可以通过 Storyboard 实现,但您将失去在原地查看图像的能力。例如,如果我在我的 swift 包中声明这个 class:
public class AppIconImageView: UIImageView {
@IBInspectable var imageName: String = "" {
didSet {
image = UIImage(named: imageName, in: Bundle.module, compatibleWith: nil)
}
}
}
然后我可以在情节提要中使用 class。提供您希望通过 imageName
运行 时间 属性 显示的图像的名称。 (然后您可以取消设置 Interface Builder 中的 'image' 设置。)
就像我提到的,图像不会显示在 Storyboard 中(@IBDesignable
在其他模块中通常很棘手),但是当 运行 时,应该加载包资源。
我在开发项目时遇到了问题。我已经决定切换到 SPM,几乎一切都按预期工作,但我一直在为一件事而奋斗,我不知道我应该怎么做。
我有几个包裹。其中之一是 UI 包,其中包含一些图像、一些可重用屏幕的自定义实现等,但最重要的是它包含一些在其他包周围使用的图标。
我有第二个包,它涵盖了我的应用程序的一部分的实现。在这里我们可以找到与这个功能相关的所有屏幕,并且它里面还有一些故事板(以后我会把这个故事板改写成代码版)。我有一个问题——因为故事板无法在运行时从其他包加载图像,所以即使在 Xcode 中我可以看到故事板有图像并且该图像来自其他包,但在运行时它不会加载。当我为此使用 Pods 时,我有一个小脚本在 Assets 文件夹形式 UI 框架与 FunctionalityFramework 之间创建引用,在此操作之后图像正确加载(类似于那里描述的:Storyboard, UIImageView. Load image from bundle)
但是我如何通过 SPM 实现这一目标呢?我无法在两个包及其文件夹之间进行引用。有什么办法可以实现吗?
Swift 5.3 添加了对 SPM 的改进以提供资源,因此完成您所要求的一种方法是让您的 swift 包出售图像,然后通过 UIViewController
支持 Storyboard 视图。
可以找到 Apple 的捆绑资源文档 here。
以下是要点:
确保您的 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
class,它将从 Bundle.module
加载图像。这可以通过 Storyboard 实现,但您将失去在原地查看图像的能力。例如,如果我在我的 swift 包中声明这个 class:
public class AppIconImageView: UIImageView {
@IBInspectable var imageName: String = "" {
didSet {
image = UIImage(named: imageName, in: Bundle.module, compatibleWith: nil)
}
}
}
然后我可以在情节提要中使用 class。提供您希望通过 imageName
运行 时间 属性 显示的图像的名称。 (然后您可以取消设置 Interface Builder 中的 'image' 设置。)
就像我提到的,图像不会显示在 Storyboard 中(@IBDesignable
在其他模块中通常很棘手),但是当 运行 时,应该加载包资源。