Xcode8:在框架中使用图像文字

时间:2017-01-24 17:22:35

标签: ios swift3 uiimage xcode8

我目前正在更新项目以使用image literals,以享受非可选图片带来的好处。该项目正在导入各种框架,框架包含图像。

在框架中,我们必须在UIImage上声明一个扩展来覆盖初始化,因为它正在查找错误包中的图像。我们做了类似的事情:

extension UIImage {   
    convenience init?(framework_named imageName: String) {
        let bundle = Bundle(for: ClassNameInFramework.self)
        self.init(named: imageName, in: bundle, compatibleWith: nil)
    }
}

我也希望在框架中使用图像文字,但与以前一样,文字正在为图像寻找错误的包,并且应用程序崩溃

有谁知道,如何指定要查找图像的图像文字?

1 个答案:

答案 0 :(得分:17)

我发现了一个非常简单的解决方法,并且惊讶于在其他帖子上找不到它。我希望它可以更优雅,但它比我认为使用串式UIImage(named:in:compatibleWith:)初始化器更可取。

我们基本上利用了_ExpressibleByImageLiteral协议,这是Xcode用来确定某个类型是否可由图像文字表达的协议。它是Swift标准库的一部分,但它不能自动完成,我想因为想要用图像文字初始化自定义类型并不常见。但是,它正是我们想要的,其行为与其他ExpressibleBy协议完全相同。

struct WrappedBundleImage: _ExpressibleByImageLiteral {
    let image: UIImage?

    init(imageLiteralResourceName name: String) {
        let bundle = Bundle(for: ClassInFramework.self)
        image = UIImage(named: name, in: bundle, compatibleWith: nil)
    }
}

请注意,我使用包装器而不是UIImage子类,这似乎是一个更好的选择。可悲的是,像UIImage这样的课程并不打算成为子类,如果你这样做,你会发现自己会遇到很多麻烦。

现在它的用法变为:

let image = ( as WrappedBundleImage).image

不像普通图像字面那样简洁,但它是我们现在所拥有的最好的图像。我们只需要记住进行as投射,否则我们的自定义初始化程序将不会被调用。

您也可以这样做:

extension UIImage {
    static func fromWrappedBundleImage(_ wrappedImage: WrappedBundleImage) -> UIImage? {
        return wrappedImage.image
    }
}

我们现在可以像这样使用它:

UIImage.fromWrappedBundleImage()

希望这有帮助!