UIImage imageNamed:不会自动选择视网膜@2x 图像

Posted

技术标签:

【中文标题】UIImage imageNamed:不会自动选择视网膜@2x 图像【英文标题】:UIImage imageNamed: does not automatically pick retina @2x images 【发布时间】:2012-10-04 18:06:44 【问题描述】:

假设我在捆绑包或资产目录中有三张图片:

    默认~iphone.png 默认@2x~iphone.png 默认-568h@2x.png

ios 4 及更高版本上,UIImage 构造函数可以采用如下图像名称:

[UIImage imageNamed:@"Default"];

当我使用 3.5 英寸视网膜显示屏 (iphone) 时,它会自动选择图像 (2)。如果在非视网膜显示器上,它会选择 (1)。这很棒。

我将图像 3 命名为为 4 英寸视网膜 (iPhone 5) 启动图像指定的名称。有没有办法命名图像(3),这样当我在 4 英寸视网膜显示器上运行时,它会返回相同的 UIImage 构造函数?

也许这还没有实现,或者我对便利性期望过高......我只是想避免在我的代码中使用任何条件逻辑来根据屏幕尺寸选择图像。

【问题讨论】:

【参考方案1】:

我也遇到了同样的问题,结果证明 iPhone 5/iPod Touch 第 5 代没有这种行为。

您必须手动确定您的应用程序是否在此类设备上运行并相应更改文件名。

我已使用此方法检查我的应用程序是否在 iPhone 5/iPod Touch 第 5 代上运行:

#define IS_PHONEPOD5() ([UIScreen mainScreen].bounds.size.height == 568.0f && [UIScreen mainScreen].scale == 2.f && UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)

然后你可以像这样调整图像名称:

if(IS_PHONEPOD5()) 
   myImageView.image = [UIImage imageNamed:@"MyImage-568h.png"];
 else 
   myImageView.image = [UIImage imageNamed:@"MyImage.png"];

更新 我还在 github (Link) 上找到了一个 UIImage 类别,它实现了您正在寻找的内容。它没有对不存在的文件的回退,但您可以自己轻松地实现它。

【讨论】:

+1 这是一个很棒的类别。感谢您的链接。然而,从技术上讲,它已经对不存在的图像进行了回退 - 它只返回 `UIImage imageNamed:' 方法以及传入的任何原始名称字符串。这对我来说是有意义的,因为在这种情况下是所需的行为。 我就是这么想的。我最终制作了一个类似的 UIImage 类别。【参考方案2】:

没有 4" 图像类型。唯一与其他所有内容不同的是包含 Default-568h@2x.png,它被用作 iPhone 5 的启动图像,并向操作系统发出信号,表明您的应用程序支持更长的屏幕和不应该是信箱的。

您必须处理不同屏幕尺寸的代码或自动布局。没有特殊的自动图像类型。它可以是标准屏幕图像类型,也可以是视网膜图像类型,与 iOS 4 以来相同。

【讨论】:

【参考方案3】:

iOS 8 中的新 API 允许您加载命名图像的视网膜版本,以前您必须自己确定文件名:

UIImage* retinaImage = [UIImage imageNamed:@"ImageName" 
    inBundle:nil compatibleWithTraitCollection:nil];

NSLog(@"screen scale: %2.2f retinaImage: %@",
    [UIScreen mainScreen].nativeScale, retinaImage);

【讨论】:

以上是关于UIImage imageNamed:不会自动选择视网膜@2x 图像的主要内容,如果未能解决你的问题,请参考以下文章

UIImage imageNamed 返回 nil

UIImage + NSCache 与 [UIImage imageNamed:]

无法使用 imageNamed 方法获取 UIImage 对象

UIImage imageWithContentsOfFile 不起作用(ImageNamed 工作正常)

UIImage 的 -imageNamed: 方法是不是适用于存储在“文档”中的图像文件?

iOS 加载图片选择imageNamed 方法还是 imageWithContentsOfFile?