使用 iOS 从捆绑包中加载图像

问题描述 投票:0回答:13

我在项目中添加了一个

.bundle
文件夹,其中填充了一些图像。 直接参考这张图片写类似的内容是否正确?:

[UIImage imageNamed:@"imageInBundle.png"];

访问和使用这些图像的最佳方法是什么?

ios objective-c uiimage
13个回答
57
投票

这是正确的,

imageNamed:
将搜索您的主包。项目中的图像,即使它们位于项目导航器中的不同组中,也将位于您的主包中,并且可以通过名称直接访问。


57
投票

如果这不起作用,请尝试

[UIImage imageNamed:@"yourbundlefile.bundle/imageInBundle.png"];

最好


40
投票

值得庆幸的是,Apple 从 iOS 8 开始为此提供了适当的 API,

imageNamed:inBundle:compatibleWithTraitCollection:

使用方式如下:

[UIImage               imageNamed:@"image-name"
                         inBundle:[NSBundle bundleForClass:self.class]
    compatibleWithTraitCollection:nil]

或快速:

let image = UIImage(named: "image-name",
                    inBundle: NSBundle(forClass: type(of:self)),
                    compatibleWithTraitCollection: nil)

或在 swift 5 中:

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

27
投票

1) 如果您正在使用捆绑包,请转到捆绑包目标并将 COMBINE_HIDPI_IMAGES 设置为 NO。 在另一种情况下,图像将转换为 tiff 格式。

2)尝试这个代码:

NSBundle *bundle = [NSBundle bundleWithURL:[[NSBundle mainBundle] URLForResource:@"YourBundle" withExtension:@"bundle"]];
NSString *imagePath = [bundle pathForResource:@"imageInBundle" ofType:@"png"];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

10
投票

斯威夫特3

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

我无法获取当前捆绑包,所以我这样做:

Bundle(for: type(of: self))

7
投票

您需要按照以下步骤操作:

  • 将图像文件添加到您的 Xcode 项目中:
  • 首先,确保您拥有要在项目中使用的图像文件。将它们拖放到您的 Xcode 项目中,确保它们添加到适当的目标。
  • 创建资源包:
  • 接下来,您将创建一个包含图像的资源包。 为此,请按照下列步骤操作: 在 Xcode 中,转到“文件”->“新建”-> 目标。在模板选择对话框中选择“iOS”或“macOS”。 向下滚动并从模板列表中选择“捆绑包”。点击 “下一步”并为您的包命名(例如“ImageResourcesBundle”)。
  • 确保目标已添加到您的主应用程序目标中。添加 图像文件到捆绑包:
  • 创建捆绑包后,请确保将图像文件添加到 捆绑包的目标。为此,请在 Xcode 项目中选择捆绑包 导航器,然后将图像文件拖放到包中 “复制捆绑资源”构建阶段。
  • 从资源包中加载图片:最后就可以加载了 使用适当的 Bundle 方法从资源包中获取图像。

以下是如何操作的示例:

快速代码

**

func getImageFromResourceBundle(named imageName: String) -> UIImage? {
    // Replace "ImageResourcesBundle" with the name of your resource bundle.
    guard let bundleURL = Bundle.main.url(forResource: "ImageResourcesBundle", withExtension: "bundle"),
          let resourceBundle = Bundle(url: bundleURL) else {
        return nil
    }
    
    // Load the image from the resource bundle.
    return UIImage(named: imageName, in: resourceBundle, compatibleWith: nil)
}

目标C代码

+(UIImage*) getImageFromResourceBundle:(NSString*) imageName
{
    NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"Resource" ofType:@"bundle"];
    NSString *imageString = [[NSBundle bundleWithPath:bundlePath] pathForResource:nameOfImage ofType:@"png"];
    
    UIImage *retrievedImage = [[UIImage alloc] initWithContentsOfFile: imageString];
    return retrievedImage;
}

然后您可以调用此函数从资源包中获取图像:

if let image = getImageFromResourceBundle(named: "imageName") {
    // Do something with the image.
} else {
    // The image couldn't be loaded.
}

6
投票

Swift 版本

@AndrewMackenzie 的回答对我不起作用。这就是有效的

let image = UIImage(named: "imageInBundle.png")
imageView.image = image

我的完整答案是这里


5
投票

因为我必须为 Swift 解决这个问题,我想我也会添加......

if let imagePath = NSBundle.mainBundle().pathForImageResource("TestImage.png")     
{
    imageView.image = NSImage(contentsOfFile: imagePath)
}

我的包内的

TestImage.png
组中有
Supporting Files


5
投票

对于 Swift 3

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

2
投票

如果您要在同一个 viewController 中多次使用它,有一个快速的方法:

在同一个类中的任意位置获取图像,方法如下:

// this fetches the image from: MyBundle.bundle/folder/to/images/myImage.png
UIImage *myImage = [self imageFromBundle:@"MyBundle" withPath:@"folder/to/images/myImage.png"];

获取图像的方法:

- (UIImage *)imageFromBundle:(NSString *)bundleName withPath:(NSString *)imageName
{
    NSURL *bundleURL = [[NSBundle mainBundle] URLForResource:bundleName withExtension:@"bundle"];
    NSBundle *bundle = [NSBundle bundleWithURL:bundleURL];
    NSString *imagePath = [bundle pathForResource:imageName ofType:nil];
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    return image;
}

或者直接从捆绑包中调用它:

UIImage *myImage = [UIImage imageNamed:@"MyBundle.bundle/folder/to/images/myImage.png"];

2
投票

如果您正在构建一个框架,并且希望

UIImage(named: "image")
的所有实例始终使用您的自定义捆绑包,您可以创建如下所示的扩展来覆盖它

// Swift 5

extension UIImage {
  convenience init?(named: String) {
    self.init(named: named, in: <#Your Bundle#>, compatibleWith: nil)
  }
}

1
投票

我在尝试解决从 Swift Package 加载图像时发现了这个问题,所以如果其他人也遇到这个问题,这就是我解决它的方法:

let image = UIImage(named: "imageName", in: Bundle.module, compatibleWith: nil)


0
投票

这在 Swift 5

中对我有用
// Empty UIImage array to store the images in it.
var icons = [UIImage]()

let fileManager = FileManager.default
let bundleURL = Bundle.main.bundleURL
let assetURL = bundleURL.appendingPathComponent("MyBundle.bundle") // Bundle URL
do {
  let contents = try fileManager.contentsOfDirectory(at: assetURL,
 includingPropertiesForKeys: [URLResourceKey.nameKey, URLResourceKey.isDirectoryKey],
 options: .skipsHiddenFiles)
  for item in contents { // item is the URL of everything in MyBundle imgs or otherwise.

      let image = UIImage(contentsOfFile: item.path) // Initializing an image
      icons.append(image!) // Adding the image to the icons array
  }
}
catch let error as NSError {
  print(error)
}
© www.soinside.com 2019 - 2024. All rights reserved.