如何在iOS的cocoapod库中使用图像资源目录
我有一个cocoapod库,其中包含两种格式的资产:如何在iOS的cocoapod库中使用图像资源目录,ios,objective-c,iphone,xcode,cocoapods,Ios,Objective C,Iphone,Xcode,Cocoapods,我有一个cocoapod库,其中包含两种格式的资产: 故事板 XCode资产目录.xcassets(带图像) 我的podspec文件包含资源包的定义: s.resource_bundle = {'SparkSetup' => ['Resources/**/*.{xcassets,storyboard}']} 在pod项目中,我有一个单独的目标,通过使用这些文件+该捆绑包的plist文件来创建一个资源捆绑包 问题是,当我在应用程序项目中使用pod时,我可以看到pod目标中有情节提要/x
- 故事板
- XCode资产目录.xcassets(带图像)
podspec
文件包含资源包的定义:
s.resource_bundle = {'SparkSetup' => ['Resources/**/*.{xcassets,storyboard}']}
在pod项目中,我有一个单独的目标,通过使用这些文件+该捆绑包的plist文件来创建一个资源捆绑包
问题是,当我在应用程序项目中使用pod时,我可以看到pod目标中有情节提要/xcassets文件,我可以轻松访问和运行情节提要,但在运行时找不到情节提要(指向.xcassets文件)中引用的图像(但在IB中正确显示)
我得到的错误是:
Could not load the "spinner" image referenced from a nib in the bundle with identifier "(null)"
我确实在products目录中看到了一个bundle文件。
要在我使用的故事板中实例化VCs,请执行以下操作:
+(NSBundle *)getResourcesBundle
{
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"SparkSetup" withExtension:@"bundle"]];
return bundle;
}
+(UIStoryboard *)getSetupStoryboard
{
UIStoryboard *setupStoryboard = [UIStoryboard storyboardWithName:@"setup" bundle:[SparkSetupMainController getResourcesBundle]];
return setupStoryboard;
}
这对于查找情节提要似乎很有效,但对于查找同一捆绑包中的.xcsets中的图像却不起作用
我做错了什么?我如何从这个故事板/代码中引用图像,并能够将这个UI pod集成到任何应用程序中
谢谢 嗯,pods不支持图像资产目录-只需在podspec中包含包含图像文件的资源包,如下所示:
s.subspec 'Resources' do |resources|
resources.resource_bundle = {'MyBundle' => ['Resources/**/*.{png}']}
end
并从pod安全访问图像,如下所示:
+(NSBundle *)getResourcesBundle
{
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"MyBundle" withExtension:@"bundle"]];
return bundle;
}
+(UIImage *)loadImageFromResourceBundle:(NSString *)imageName
{
NSBundle *bundle = [MyClass getResourcesBundle];
NSString *imageFileName = [NSString stringWithFormat:@"%@.png",imageName];
UIImage *image = [UIImage imageNamed:imageFileName inBundle:bundle compatibleWithTraitCollection:nil];
return image;
}
这解决了在cocoapod中处理图像/资源的所有问题。好吧,图像资产目录不受Pod的支持-只需在podspec中包含包含图像文件的资源包,如下所示:
s.subspec 'Resources' do |resources|
resources.resource_bundle = {'MyBundle' => ['Resources/**/*.{png}']}
end
并从pod安全访问图像,如下所示:
+(NSBundle *)getResourcesBundle
{
NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle bundleForClass:[self class]] URLForResource:@"MyBundle" withExtension:@"bundle"]];
return bundle;
}
+(UIImage *)loadImageFromResourceBundle:(NSString *)imageName
{
NSBundle *bundle = [MyClass getResourcesBundle];
NSString *imageFileName = [NSString stringWithFormat:@"%@.png",imageName];
UIImage *image = [UIImage imageNamed:imageFileName inBundle:bundle compatibleWithTraitCollection:nil];
return image;
}
这解决了在cocoapod中处理图像/资源的所有问题。如果您使用swift
class func loadImage(name: String) -> UIImage? {
let podBundle = NSBundle(forClass: MyClass.self)
if let url = podBundle.URLForResource("MyBundleName", withExtension: "bundle") {
let bundle = NSBundle(URL: url)
return UIImage(named: name, inBundle: bundle, compatibleWithTraitCollection: nil)
}
return nil
}
如果您使用的是swift
class func loadImage(name: String) -> UIImage? {
let podBundle = NSBundle(forClass: MyClass.self)
if let url = podBundle.URLForResource("MyBundleName", withExtension: "bundle") {
let bundle = NSBundle(URL: url)
return UIImage(named: name, inBundle: bundle, compatibleWithTraitCollection: nil)
}
return nil
}
至少从Cocoapods的1.0.1版开始,支持图像资产目录 在我的Swift 4.2代码中,我使用了:
public static var GoogleIcon: UIImage {
let bundle = Bundle(for: self)
log.msg("bundle: \(bundle)")
return UIImage(named: "GoogleIcon", in: bundle, compatibleWith: nil)!
}
在我的pod规范中,我使用了:
s.resources = "SMCoreLib/Assets/*.xcassets"
当我使用模拟器构建时,.car文件确实会显示在框架中:
cd /Users/<snip>/SMCoreLib.framework
ls
Assets.car Info.plist SMCoreLib
cd/Users//SMCoreLib.framework
ls
Assets.car Info.plist SMCoreLib
至少从Cocoapods的1.0.1版开始,支持图像资产目录
在我的Swift 4.2代码中,我使用了:
public static var GoogleIcon: UIImage {
let bundle = Bundle(for: self)
log.msg("bundle: \(bundle)")
return UIImage(named: "GoogleIcon", in: bundle, compatibleWith: nil)!
}
在我的pod规范中,我使用了:
s.resources = "SMCoreLib/Assets/*.xcassets"
当我使用模拟器构建时,.car文件确实会显示在框架中:
cd /Users/<snip>/SMCoreLib.framework
ls
Assets.car Info.plist SMCoreLib
cd/Users//SMCoreLib.framework
ls
Assets.car Info.plist SMCoreLib
Swift 3版
private func getImageFromBundle(name: String) -> UIImage {
let podBundle = Bundle(for: YourClass.self)
if let url = podBundle.url(forResource: "YourClass", withExtension: "bundle") {
let bundle = Bundle(url: url)
return UIImage(named: name, in: bundle, compatibleWith: nil)!
}
return UIImage()
}
Swift 3版本
private func getImageFromBundle(name: String) -> UIImage {
let podBundle = Bundle(for: YourClass.self)
if let url = podBundle.url(forResource: "YourClass", withExtension: "bundle") {
let bundle = Bundle(url: url)
return UIImage(named: name, in: bundle, compatibleWith: nil)!
}
return UIImage()
}
只有这对我有效(Swift 3和Swift 4) 然后按如下方式使用:
ImagesHelper.myImage
与的答案一样,不要忘记更新podspec文件,如:
s.resource_bundles = {
'YourClass' => ['YourPodName/*/Assets.xcassets']
}
只有这对我有效(Swift 3和Swift 4) 然后按如下方式使用:
ImagesHelper.myImage
与的答案一样,不要忘记更新podspec文件,如:
s.resource_bundles = {
'YourClass' => ['YourPodName/*/Assets.xcassets']
}
你喜欢这样吗
s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'
你喜欢这样吗
s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'
您可以使用POD的包id访问POD中的图像
您可以使用POD的包id访问POD中的图像
在pod规范的资源中添加
.xcasets
文件,并使用以下UIImage init:
extension UIImage {
convenience init?(podAssetName: String) {
let podBundle = Bundle(for: ConfettiView.self)
/// A given class within your Pod framework
guard let url = podBundle.url(forResource: "CryptoContribute",
withExtension: "bundle") else {
return nil
}
self.init(named: podAssetName,
in: Bundle(url: url),
compatibleWith: nil)
}
}
在pod规范的资源中添加
.xcasets
文件,并使用以下UIImage init:
extension UIImage {
convenience init?(podAssetName: String) {
let podBundle = Bundle(for: ConfettiView.self)
/// A given class within your Pod framework
guard let url = podBundle.url(forResource: "CryptoContribute",
withExtension: "bundle") else {
return nil
}
self.init(named: podAssetName,
in: Bundle(url: url),
compatibleWith: nil)
}
}
我自己用椰子豆来解决这个问题。我没有使用UIImage,而是添加了一个捆绑方法。该方法尝试定位给定名称的内部捆绑包,但返回到原始捆绑包。这允许代码在使用pod的应用程序代码以及pod代码本身中工作
extension Bundle {
/**
Locate an inner Bundle generated from CocoaPod packaging.
- parameter name: the name of the inner resource bundle. This should match the "s.resource_bundle" key or
one of the "s.resoruce_bundles" keys from the podspec file that defines the CocoPod.
- returns: the resource Bundle or `self` if resource bundle was not found
*/
func podResource(name: String) -> Bundle {
guard let bundleUrl = self.url(forResource: name, withExtension: "bundle") else { return self }
return Bundle(url: bundleUrl) ?? self
}
}
然后在viewdiload
方法中,或者在任何你有图像设置代码的地方,放置类似这样的东西,其中“ClassFromPod”指的是CocoaPod中的Swift类,“ResourceName”是pod中内部包的名称(你应该能够在“Pods/Projects”中使用Xcode项目导航器查看包)--嵌入式捆绑包具有乐高图标和“捆绑包”后缀。)
如您所见,UIImage API保持不变,只是所使用的捆绑包不同,这取决于它在运行时找到的内容。我自己的CocoaPods解决方案。我没有使用UIImage,而是添加了一个捆绑方法。该方法尝试定位给定名称的内部捆绑包,但返回到原始捆绑包。这允许代码在使用pod的应用程序代码以及pod代码本身中工作
extension Bundle {
/**
Locate an inner Bundle generated from CocoaPod packaging.
- parameter name: the name of the inner resource bundle. This should match the "s.resource_bundle" key or
one of the "s.resoruce_bundles" keys from the podspec file that defines the CocoPod.
- returns: the resource Bundle or `self` if resource bundle was not found
*/
func podResource(name: String) -> Bundle {
guard let bundleUrl = self.url(forResource: name, withExtension: "bundle") else { return self }
return Bundle(url: bundleUrl) ?? self
}
}
然后在viewdiload
方法中,或者在任何你有图像设置代码的地方,放置类似这样的东西,其中“ClassFromPod”指的是CocoaPod中的Swift类,“ResourceName”是pod中内部包的名称(你应该能够在“Pods/Projects”中使用Xcode项目导航器查看包)--嵌入式捆绑包具有乐高图标和“捆绑包”后缀。)
如您所见,UIImage API保持不变,只是所使用的捆绑包不同,这取决于它在运行时找到的内容。我仍然无法让它工作,因为上面没有任何解决方案。 我的Pod中有一个Assets.xcsets文件 在我的Pod类中,我想访问资产中的图像 具体如下:
s.resource_bundles = {
'SWDownloadPlayButton' => ['SWDownloadPlayButton/Assets/Assets.xcassets']
}
func getImage(named name: String) -> UIImage {
// Use a random singleton class in your project.
// Emphasis on class, structs won't work.
let bundle = Bundle(for: [random class].self)
if let image = UIImage(named: name, in: bundle, compatibleWith: nil) {
return image
}
return .init()
}
使用此帮助程序:
public struct ImagesHelper {
private static var podsBundle: Bundle {
let bundle = Bundle(for: SWDownloadPlayButton.self)
return Bundle(url: bundle.url(forResource: "SWDownloadPlayButton",
withExtension: "bundle")!)!
}
private static func imageFor(name imageName: String) -> UIImage {
return UIImage.init(named: imageName, in: podsBundle, compatibleWith: nil)!
}
public static var download_icon: UIImage {
return imageFor(name: "download_icon")
}
}
但是无论我在我的Pod类中做什么(不是在示例项目中)…就像这样
s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'
var centerImage: UIImage = ImagesHelper.download_icon.withRenderingMode(.alwaysTemplate) {
didSet {
updateImage()
}
}
我的centerImage仍然为零如果没有上述解决方案,我仍然无法使其正常工作。 我的Pod中有一个Assets.xcsets文件 在我的Pod类中,我想访问资产中的图像 具体如下:
s.resource_bundles = {
'SWDownloadPlayButton' => ['SWDownloadPlayButton/Assets/Assets.xcassets']
}
func getImage(named name: String) -> UIImage {
// Use a random singleton class in your project.
// Emphasis on class, structs won't work.
let bundle = Bundle(for: [random class].self)
if let image = UIImage(named: name, in: bundle, compatibleWith: nil) {
return image
}
return .init()
}
使用此帮助程序:
public struct ImagesHelper {
private static var podsBundle: Bundle {
let bundle = Bundle(for: SWDownloadPlayButton.self)
return Bundle(url: bundle.url(forResource: "SWDownloadPlayButton",
withExtension: "bundle")!)!
}
private static func imageFor(name imageName: String) -> UIImage {
return UIImage.init(named: imageName, in: podsBundle, compatibleWith: nil)!
}
public static var download_icon: UIImage {
return imageFor(name: "download_icon")
}
}
但是无论我在我的Pod类中做什么(不是在示例项目中)…就像这样
s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'
var centerImage: UIImage = ImagesHelper.download_icon.withRenderingMode(.alwaysTemplate) {
didSet {
updateImage()
}
}
如果您使用SwiftUI,使用
图像,我在centerImage上仍然得到一个零。init(\uu name:String,bundle:bundle?)
初始值设定项不起作用,您必须这样初始化它:
s.resource_bundles = {
'SWDownloadPlayButton' => ['SWDownloadPlayButton/Assets/Assets.xcassets']
}
func getImage(named name: String) -> UIImage {
// Use a random singleton class in your project.
// Emphasis on class, structs won't work.
let bundle = Bundle(for: [random class].self)
if let image = UIImage(named: name, in: bundle, compatibleWith: nil) {
return image
}
return .init()
}
如果您使用的是Swif