访问资源目录的pathForResource

70

看起来:

[[NSBundle mainBundle] pathForResource:@"name" ofType:@"png"];

无法返回 Images.xcassets 资源目录内的资源路径。我也尝试了:

[[NSBundle mainBundle] pathForResource:@"name" ofType:@"png" inDirectory:@"Images"];

[[NSBundle mainBundle] pathForResource:@"name" ofType:@"png" inDirectory:@"Images.xcassets"];

但都没有成功。

有人成功地检索了目录中的资源路径吗?


我还需要图像的实际路径,因为我不想使用imageNamed(破碎的缓存),而且Asset Catalogs也没有编程访问权限。 - Alper
@MobileVet,你找到解决方案了吗? - Keab42
@Keab42 不是,我刚刚遇到另一个我想要它的情况! :) - MobileVet
6个回答

27

有同样的问题,但我认为除以下情况外,我们无法通过pathForResource:访问它:

UIImage* image = [UIImage imageNamed:@"name-in-asset-catalog"];

已经有文献记录

资产目录中的每个集合都有一个名称。 您可以使用该名称以编程方式加载集合中包含的任何单个图像。 要加载图像,请调用UIImage:imageNamed:方法,传递包含图像的集合的名称。

我在应用程序的已编译包中发现了一个名为"Assets.car"的文件,我认为它是我的项目中的所有图像集,应该已经被压缩或其他处理过。

参考苹果文档:

Xcode 5 根据您项目的部署目标提供资产目录的不同功能:

  • 对于所有项目,可以使用设置名称加载单个图像。
  • 对于部署目标为 iOS 7 的项目,Xcode将您的资产目录编译到减少应用程序下载时间的运行时二进制文件格式中。

就是这样。

我还在寻找一种不使用imageNamed:的方法,我不想让运行时缓存我的图像。


4
我在这里遇到了与缓存图像有关的相同问题:https://dev59.com/iWIj5IYBdhLWcg3wwHpr#mdQKoYgBc1ULPQZFsR3k。当使用资源目录时,似乎imageNamed:caching不像预期那样起作用,因为即使在内存警告时系统也从未释放内存。 - knl
6
我可以证实这一点。内存并没有被释放。iOS 的这个部分相当不稳定。 - Alper
如果在资产中有一个文件夹,而我只需要其中的照片怎么办?请问有什么帮助吗? - Yucel Bayram
同样的问题。iOS 11. XCode 9.1 - gaskbr

13

我想要访问一些向量资源以创建本地资源的UNNotificationAttachment,所以我想到了这个帮助类。它基本上只是从资源中获取图像,将其数据保存到磁盘并返回文件URL。希望能帮助到某些人。

import UIKit

class AssetExtractor {

    static func createLocalUrl(forImageNamed name: String) -> URL? {

        let fileManager = FileManager.default
        let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
        let url = cacheDirectory.appendingPathComponent("\(name).png")

        guard fileManager.fileExists(atPath: url.path) else {
            guard
                let image = UIImage(named: name),
                let data = UIImagePNGRepresentation(image)
            else { return nil }

            fileManager.createFile(atPath: url.path, contents: data, attributes: nil)
            return url
        }

        return url
    }

}

1
我之前也遇到过同样的问题,这种方法非常有效。感谢分享。 - RommelTJ
太好了!我把它变成了UIImage类的静态函数。 - Jon Vogel

11
[UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.png", [[NSBundle mainBundle] resourcePath], imgName]];
:图片集的名称,不关心图片在图片集中的真实名称。

1
除了主要的捆绑包之外,它无法处理其他捆绑包中的图像。 - user1010819
谢谢,伙计。你的方法是对 + (UIImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle compatibleWithTraitCollection:(UITraitCollection *)traitCollection 的一个很好的替代方式。它是在 iOS 8.0 中引入的,而我需要兼容 7.x.x 版本。 - Arthur Gevorkyan

2

尝试使用在“编译资源目录”步骤中确定的图像名称。您会在构建输出中找到这个。一定要展开文字记录 - 您应该看到类似于以下内容:

/* com.apple.actool.compilation-results */
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-800-Portrait-736h@3x.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-800-667h@2x.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700@2x.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700-568h@2x.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700-Landscape~ipad.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700-Landscape@2x~ipad.png

使用 Xcode 6.1.1 测试了 +[UIImage imageNamed:] 方法。


0

对于启动图像和应用程序图标,它们的图像路径分别通过UILaunchImages和CFBundleIcons Info.plist键获得。当使用资源目录进行应用程序构建时,这些图像似乎是单独生成的,并更新Info.plist值(如果没有,则这些键直接由Xcode UI编写)。您可能需要编写一些代码来确定要使用的正确子字典,但是在这种情况下,可以单独使用这些图像,并且可以避免使用imageNamed。


-3

虽然每个xcassets项目中都有一个Contents.json文件(见下文),其中包含该项目图像的文件名,但似乎无法在文件系统级别上访问它。所有图像在编译时都放置在单个文件系统文件夹中。json文件是自动生成的,不应进行编辑,但它提供了一个解决方法的模板。

为每个文件命名一个一致的后缀以匹配json文件中出现的相应语言环境、比例和子类型。这需要手动选择每个资源的“在Finder中显示”选项并重命名每个文件,但完成后,您可以使用pathForResource与函数结合使用,将适当的后缀添加到基本资源名称中,以检索适当大小的图像。

检索路径的示例代码:

NSString *imageName = @"Add to Cart";
NSString *imageSuffix = [self someMethodThatDeterminesSuffix]; // Example: "-iphone-2x-retina4"
NSString *imagePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%@%@", imageName, imageSuffix] ofType:@"png"];

“Add to Cart” 图像资产的示例 Contents.json 文件:

{
  "images" : [
    {
      "idiom" : "iphone",
      "scale" : "1x",
      "filename" : "Add to Cart-iphone-1x.png"
    },
    {
      "idiom" : "iphone",
      "scale" : "2x",
      "filename" : "Add to Cart-iphone-2x.png"
    },
    {
      "idiom" : "iphone",
      "filename" : "Add to Cart-iphone-2x-retina4.png",
      "subtype" : "retina4",
      "scale" : "2x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接