如何在iOS的cocoapod库中使用图像资产目录
我有一个cocoapod库,其中包含2种格式的资产:
- a .storyboard
- XCode资产目录.xcassets(带图像)
我的podspec
文件包含资源包的定义:
s.resource_bundle = {'SparkSetup' => ['Resources/**/*.{xcassets,storyboard}']}
我在pod项目中有一个单独的目标,通过使用这些文件+该包的plist文件来创建资源包。
事情是,当我在应用程序项目中使用pod时 – 我可以看到storyboard / xcassets文件位于pod目标中,我可以轻松访问和运行故事板,但故事板中引用的图像(到.xcassets文件)是在运行时未找到(但在IB中正确显示)。
我得到的错误是:
Could not load the "spinner" image referenced from a nib in the bundle with identifier "(null)"
我确实在products目录中看到了一个bundle文件。 要在故事板中实现VC,我使用:
+(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; }
这似乎适用于查找故事板,但不适用于在同一捆绑中的.xcassets中查找图像。
我究竟做错了什么? 如何从这个故事板/代码中引用图像,并能够将此UI pod集成到任何应用程序中?
谢谢!
至少从Cocoapods 1.0.1版开始,支持图像资产目录。
在我的Swift代码中,我使用了:
public static var GoogleIcon:UIImage { let bundle = NSBundle(forClass: self) Log.msg("bundle: \(bundle)") return UIImage(named: "GoogleIcon", inBundle: bundle,compatibleWithTraitCollection: nil)! }
在我的pod规范中,我使用了:
s.resources = "SMCoreLib/Assets/*.xcassets"
当我使用模拟器构建时,.car文件确实显示在框架中:
cd /Users//SMCoreLib.framework ls Assets.car Info.plist SMCoreLib
好吧,不支持通过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 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)
public struct ImagesHelper { private static var podsBundle: Bundle { let bundle = Bundle(for: YourClass.self) return Bundle(url: bundle.url(forResource: "YourClass", withExtension: "bundle")!)! } private static func imageFor(name imageName: String) -> UIImage { return UIImage.init(named: imageName, in: podsBundle, compatibleWith: nil)! } public static var myImage: UIImage { return imageFor(name: "imageName") } }
然后使用如下:
ImagesHelper.myImage
和@Chris Prince的回答一样,不要忘记更新你的podspec文件,如:
s.resource_bundles = { 'YourClass' => ['YourPodName/*/Assets.xcassets'] }
在你podspec做这样的
s.resources = 'RootFolder/**/*.{lproj,storyboard,xcdatamodeld,xib,xcassets,json}'
您可以使用其捆绑ID从容器访问图像
NSBundle * bundle = [NSBundle bundleWithIdentifier:@"bundle id of your pod"]; UIImage * image = [UIImage imageNamed:@"imageName" inBundle:bundle compatibleWithTraitCollection:nil];
在pod规范的资源中添加.xcassets
文件,并使用以下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) } }