iOS - UIImage imageNamed:在设备上返回null

12
[UIImage imageNamed:filename]

此方法只在设备上返回 null。

我知道这是一个众所周知的问题,通常是由于模拟器不区分大小写造成的。我已经尝试了这里提出的解决方案:UIImage imageNamed 返回 nil,但对我都没有用。

情况很简单:我有4个文件,命名为Bar@2x~ipad.png、Bar@2x~iphone.png、Bar~ipad.png和Bar~iphone.png。它们全部位于带有目标复选框的项目中。

NSLog(@"%@",[UIImage imageNamed:@"Bar"]);

那行代码对于设备返回了 null,我真的不知道我现在做错了什么。

8个回答

5

我最近也遇到了这样的问题。

在文件名和路径方面进行试验后,有时候清理并重新构建项目会有所帮助。


我非常确定我以前做过几次。现在它起作用了。谢谢。 - Gricha
检查:XCode - Build Phases - Copy Bundle Resources - {查看是否有图像可用} 添加并运行. - Vicky

4

最近我也遇到了同样的情况。

我的解决方法是将扩展名添加到文件名中。

[UIImage imageNamed:@"Bar.png"]

谢谢。我刚试了一下,不幸的是它在我的情况下没有帮助。 - Gricha
对于 PNG 这种文件格式不应该有影响,也许你遇到了另一种文件格式。 - Daij-Djan
3
不,它是PNG格式的,而且这个负评似乎不太合适。 - Gabriele Petronella
1
同时,报复性的负评也是一种可怕的行为,请避免这样做。 - Gabriele Petronella

2

完全清理您的构建并重新构建:

  1. 从设备中删除应用程序
  2. 在Xcode中选择“选项-清除整个构建目录”(⌘-Shift-K)
  3. 退出Xcode
  4. 删除~/Library/Developer/Xcode/DerivedData
  5. 重新启动Xcode,构建和运行

1

这刚刚发生在我身上,而且很难发现:我有一张图片在设备上是空的。

logoWhite.png

我的代码:

[[UINavigationBar appearance] setBackgroundImage:[UIImage imageNamed:@"LogoWhite"] forBarMetrics:UIBarMetricsDefault];

经过一段时间的调试,我注意到图像名称以大写字母开头。显然,在忽略大小写的OSX文件系统上并不重要。iOs文件系统不是这样的,因此该图像在模拟器上工作但在设备上却没有。我敢打赌,所有有关清除派生数据和重新构建的解决方案最终都会随机更改图像名称,并且这也会奏效。只是为了将来参考 :)

OP实际上提到他已经检查了文件名的大小写,因为这是一个众所周知的问题(模拟器不区分大小写,而设备区分大小写)。因此,在这种情况下,文件名并不是问题所在。 - siburb

0

我遇到了这个问题并已经解决了。我在下面列出了解决方案,供参考。

我有几张图片,使用[UIImage imageNamed:filePath]来显示它们。除了一张图像在模拟器/设备上无法显示,其他所有图像都显示良好,但是在OS X上所有图像都可以看到。对于该图像,[UIImage imageNamed]始终返回null。

经过几分钟的调查,我发现引起问题的图像文件大小很大:4.1M,而其他图像大约800KB,它们在尺寸上几乎相同。

然后我尝试在图像编辑器中打开它,然后重新保存它。之后,大小降至800K。问题解决了。

我猜测的原因:

  1. [UIImage imageNamed:filePath]有一个最大文件大小限制吗?(可能性较低,但需要检查官方文件)

  2. 图像本身存在某些错误。但是OS X比iOS具有更好的容错能力。因此,iOS无法读取并返回null。这个问题就像OS X可以播放比iOS支持更多编解码器的视频文件类型一样。

因此,如果您将来遇到此问题,请花几秒钟查看文件大小。希望有所帮助。


0

我也遇到了同样的问题:XCode - Build Phases - Copy Bundle Resources -{查看是否有图像可用}- 添加{图像} - 清理 - 删除应用程序 - 运行


0

我想在以上所有解决方案中再添加一个重要的点

确保将您的图像资源添加到正确的目标中

如果开发人员错误地将链接与资源和目标搞混,则会出现问题。

如果您有多个目标,请仔细检查资源是否设置为正确的目标。

附上屏幕截图示例,以防多个目标之间的资源链接。

enter image description here


0

这是一个奇怪的问题,直到本周我才看到。

以下是我的发现和解决方法。

在我的 iPhone 应用程序中,我下载图像并将其存储在本地,这一直很好用。

但现在当我运行相同的代码时,它突然无法使用 imageNamed 函数创建 UIImage,而且现在返回 nil。

不过有三点需要注意:

  1. 这段代码以前是能用的,使用相同的源代码和 .png 图像文件。我不确定我的 XCode 6.x 或 iOS 8.x 是否在此期间自动更新了。
  2. 该代码在 iPhone 模拟器上(使用相同的图像文件)仍然可以正常工作。但是在真实设备上却不能正常工作。
  3. 请查看下面的代码。当 UIImage:imageNamed 失败时,我运行了一些代码来检查文件是否存在...而它确实存在。然后,我使用 NSData:contentsAtPath 加载了文件的二进制数据(这也证明文件存在且位于正确的文件夹中),然后从中创建了一个 UIImage,它可以正常工作。

咦?!

UIImage* img = [UIImage imageNamed:backgroundImageFilename];
if (img != nil)
{
    //  The image loaded fine (this always worked before).  Job done.
    //  We'll set our UIImageView "imgBackgroundView" to contain this image.
    self.imgBackgroundView.image = img;
}
else
{
    //  We were unable to load the image file for some reason.
    //  Let's investigate why.

    //  First, I checked whether the image was actually on the device, and this returned TRUE...
    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:backgroundImageFilename];
    if (fileExists)
        NSLog(@"Image file does exist.");
    else
        NSLog(@"Image file does not exist.");


    //  Next, I attempted to just load the bytes in the file, and amazingly, this also worked fine...
    NSData *data = [[NSFileManager defaultManager] contentsAtPath:backgroundImageFilename];
    if (data != nil)
    {
        //  ..and then I COULD actually create a UIImage out of it.
        img = [UIImage imageWithData:data];
        if (img != nil)
        {
            //  We have managed to load the .png file, and can now
            //  set our UIImageView "imgBackgroundView" to contain this image.
            self.imgBackgroundView.image = img;
        }
    }
}

就像我说的那样,这段代码确实提供了解决这个问题的方法,但很奇怪的是它突然开始出现。

并且,我应该说一下,我尝试了这个帖子中的其他建议,清理项目,删除DerivedData,完全从设备上删除应用程序等等,但它们没有产生任何影响。

我想知道是否还有其他人遇到这个问题,并发现我的代码示例对他们也有效。

更新

我真是个白痴。

我不确定UIImage:imageNamed函数是否改变了什么(如果确实改变了,为什么在iPhone 8.1模拟器上仍然可以正常工作),但我发现下面这行代码确实可以正常工作:

UIImage* img = [[UIImage alloc] initWithContentsOfFile:backgroundImageFilename];

因此,看起来您应该使用此函数来加载不属于您应用程序包的图像。


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