【问题标题】:Access Asset Catalog pathForResource访问资产目录 pathForResource
【发布时间】:2013-09-28 21:16:43
【问题描述】:

看来:

[[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(损坏的缓存),事实证明资产目录也损坏了,没有程序访问。
  • @MobileVet 你找到解决方案了吗?
  • @Keab42 不,我刚刚遇到了另一个我想要的案例! :)

标签: ios7 xcode5 nsbundle


【解决方案1】:

同样的问题,但我认为我们无法通过pathForResource: 访问它,除了以下内容:

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

明明是documented

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

我发现编译出来的app包里有一个名为"Assets.car"的文件出来了,我觉得是我项目中的全部图片集,应该是压缩包什么的.

请参阅 Apple 的文档:

Xcode 5 为资产目录提供了不同的功能,具体取决于 关于您项目的部署目标:

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

就是这样。

我也在寻找一种不使用imageNamed:的方法,我不希望运行时缓存我的图像。

【讨论】:

  • 我在stackoverflow.com/questions/19919113/… 处缓存图像时遇到了同样的问题。看起来像 imageNamed: 使用资产目录时缓存无法按预期工作,因为系统永远不会释放内存,甚至在内存警告时也不会。
  • 我可以验证这一点。内存没有被释放。 iOS 的这一部分已经很糟糕了。
  • 如果资产中有一个文件夹,我只需要这个文件夹中的照片怎么办?请问有什么帮助吗?
  • 这里有同样的问题。 iOS 11.. XCode 9.1
【解决方案2】:

虽然有一个 Contents.json 文件(见下文)与 xcassets 中的每个项目相关联,其中包含该项目图像的文件名,但它似乎无法在文件系统级别访问。所有图像在编译时都放在一个文件系统文件夹中。 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"];

“添加到购物车”图片资源的 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"
  }
}

【讨论】:

    【解决方案3】:
    [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.png", [[NSBundle mainBundle] resourcePath], imgName]];
    

    imgName:Image set的名称,不关心Image set中图片的真实名称。

    【讨论】:

    • 除主包外,不适用于任何其他包中的图像。
    • 谢谢,伙计。你这样做的方式很好地替代了 + (UIImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle compatibleWithTraitCollection:(UITraitCollection *)traitCollection。它是在 iOS 8.0 中引入的,我也需要涵盖 7.x.x。
    【解决方案4】:

    尝试使用“编译资产目录”步骤中确定的图像名称。您将在构建输出中找到它。请务必展开文字记录 - 您应该会看到如下内容:

    /* 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
    

    使用 +[UIImage imageNamed:] 和 Xcode 6.1.1 测试。

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        我想访问一些矢量资产以使用本地资源创建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
            }
        
        }
        

        【讨论】:

        • 我遇到了同样的问题,效果很好。感谢分享。
        • 不错!我把它作为 UIImage 类的静态函数。
        猜你喜欢
        • 2013-06-07
        • 1970-01-01
        • 2019-12-26
        • 2018-02-05
        • 1970-01-01
        • 1970-01-01
        • 2015-01-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多