从iOS 8框架中加载图像

33
我正在尝试从我正在编写的 iOS 8 框架(使用 Swift)中加载图像。我正在使用 Xcode 6 Beta 6。如果图像存储在我的框架的 Images.xcassets 中,那么此代码无法正常工作(即无法加载图像):
let image = UIImage(named: "Background.png")
如果图片存储在宿主应用程序(使用该框架)的 Images.xcassets 中,则可以从框架内部的代码正确加载图片。 我可以看到框架的 Images.xcassets 包含在 Copy Bundle Resources 阶段中。 我还在框架中使用storyboard文件作为资源; 这也能被正确加载。 我已尝试重命名框架的 Images.xcassets 以避免与宿主应用程序发生某种名称冲突,但这也不起作用。
5个回答

72

尽管@Renatus的答案是完全有效的,并且解决了核心问题(需要指定框架的捆绑包),但我想发布我选择的解决方案,因为它稍微更加直接:

Swift 3.0/4.0/5.0

let image = UIImage(named: "YourImage", in: Bundle(for: YOURFRAMEWORKCLASS.self), compatibleWith: nil)

或者,您可以使用此模式来处理非class(也称为非“静态”)函数:

let image = UIImage(named: "YourImage", in: Bundle(for: type(of: self)), compatibleWith: nil)

或者对于class函数,可以使用这个模式:

let image = UIImage(named: "YourImage", in: Bundle(for: self), compatibleWith: nil)

这些替代方案更适合剪切和粘贴。


4
对我有用,但最好详细说明YOURFRAMEWORKCLASS的含义。我最初尝试了总体头文件,但没有成功,所以我用框架的主入口点类替换了它...这样做有效了。 - jowie
@Daniel 感谢你的回答,它救了我的命,因为我被这个问题困扰了3天,而你的答案完美地解决了我的问题...! - Muhammad Danish Qureshi

13

UIImage(named: "Background.png") 在内部调用了 NSBundle.mainBundle()。因此,您的代码试图在主机应用程序的包中查找资源,而不是在框架的包中查找。要从您的框架的包中加载 UIImage,请使用以下代码片段:

let frameworkBundle = NSBundle(forClass: YOURFRAMEWORKCLASS.self)
let imagePath = frameworkBundle.pathForResource("yourImage.png", ofType: "")
if imagePath != nil {
  result = UIImage(contentsOfFile: imagePath!)
}

编辑:添加了解释(感谢milz)


2
虽然您的答案可能解决了问题,但如果您能提供问题的描述以及您的答案如何解决它,那就更好了。这是进一步改善当前和未来答案的建议。 - Luís Cruz
1
在这里,您可能不应该使用带有扩展名的图像名称 yourImage.png - 您希望UIKit在@2、@3等之间进行选择。 - Zorayr

3

另一个选项是分配bundle标识符,与分配类相比,这更有助于可读性。

Swift 3中:

UIImage(named: "MyImage", in: Bundle(identifier: "bundleIdentifier"), compatibleWith: nil)

3

在Swift 3.0中:

let currentBundle = Bundle(for: YOURCLASS.self)
guard let path = currentBundle.path(forResource: imageName, ofType: "jpg") else {  return defaultImage }
return UIImage(contentsOfFile: path) ?? defaultImage

0

被接受的答案对我没用。这里有一种绝对可靠的方法来加载嵌入在动态框架中的图像:

    var bundle = NSBundle(forClass: self.classForCoder)

    if let bundlePath = NSBundle(forClass: self.classForCoder).resourcePath?.stringByAppendingString("/MYLIB.bundle"), resourceBundle = NSBundle(path: bundlePath) {
        bundle = resourceBundle
    }

    let image = UIImage(named: "my-embedded-image", inBundle: bundle, compatibleWithTraitCollection: nil)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接