Xcode8:图像文字在框架中的使用
Posted
技术标签:
【中文标题】Xcode8:图像文字在框架中的使用【英文标题】:Xcode8: Usage of image literals in frameworks 【发布时间】:2017-01-24 17:22:35 【问题描述】:我目前正在更新一个项目以使用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)
我也想在框架中使用图像文字,但和以前一样,文字正在为图像寻找错误的捆绑包,应用程序崩溃。
有谁知道,如何指定要在哪个包中查找图像的图像文字?
【问题讨论】:
很遗憾无法指定。图像文字调用init(named:)
初始化器,它在主包中查找。
@dan 你能指点我一些文档吗?
【参考方案1】:
我发现了一个非常简单的解决方法,很惊讶在其他帖子的任何地方都找不到它。我希望它可以更优雅,但在我看来,它比使用字符串类型的 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(?)
希望这会有所帮助!
【讨论】:
不错的解决方案。唯一可能成为问题的是默认图像文字在“媒体库”列表中仍然可见。这是 Xcode 右下角的列表。当人们使用此列表中的文字时,这可能会导致问题,因为这些文字仍然指向主 Bundle。 你是对的@bartosss,感谢您的评论。我已经更新了我上面的答案,改为使用可选项,以防我们错误地提供了主包中的文字。 @diegomontoyas_ExpressibleByImageLiteral
在技术上不是私有 API 吗?
它是一个公共协议github.com/apple/swift/blob/master/stdlib/public/core/…以上是关于Xcode8:图像文字在框架中的使用的主要内容,如果未能解决你的问题,请参考以下文章
Xcode 8.3 和 Swift 3:在 UICollectionView 中的单元格中显示图像,从 URL 获取并存储在 NSMutableArray