iPhone 5视网膜屏幕的图片

19

iPhone 5发布了,屏幕尺寸和分辨率都有所增加。

当我们在iPhone 4(视网膜屏幕)上使用图像时,只需在图像名称后面添加“@2x”即可。请问是否可以为新的iPhone屏幕添加不同的图像(背景、按钮等)?

第二个问题:我的应用程序中是否可以有单独的XIB文件:适用于旧版iPhone和新版iPhone(就像适用于iPhone和iPad一样)?

谢谢!


1
你应该将不同的问题分成不同的问题。 - Jeff Kelley
5个回答

50

以下是我关于这个主题的博客摘录:

[UIImage imageNamed:]在Retina设备上运行时会自动加载@2x版本的图像。但遗憾的是,当在iPhone 5上运行时,imageNamed:不会自动加载-568h@2x版本的图像。

有时这并不重要,例如图标和非全屏图形在iPhone 4和5上可能是相同的。但是,如果您有全屏背景图像或用于工具栏等的全宽度/高度背景图像,则会遇到问题。您的480高度的图像很可能会被拉伸(结果可能看起来很可怕)。

您可以手动检查屏幕大小并像这样加载正确的图像:

UIImage* myImage;
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f) {
   myImage = [UIImage imageNamed:@"myImage-568h.png"];
} else {
   myImage = [UIImage imageNamed:@"myImage.png"];
}

有一种方法可以改变UIImage imageNamed的行为,使其自动加载正确的图像。详情请参见下面的链接。

更多信息请访问:http://pervasivecode.blogspot.co.uk/2012/09/making-apps-work-on-iphone-5-screen-size.html

编辑:@Sound Blaster和@GrizzlyNetch是正确的,在代码中应该使用imageNamed:@"myImage-568h.png",但实际文件名应该是myImage-568h@2x.png。如果不这样做,则比例是不正确的,就像他们说的那样。


2
我认为,正确的图像名称是“myImage-568h.png” - 不带@2x。 - Sound Blaster
2
另一个解决方案可以在这里找到:http://angelolloqui.com/blog/20-iPhone5-568h-image-loading - Angel G. Olloqui
1
2Ben:我同意Sound Blaster的观点,@2x后缀不应该存在。这是因为使用后缀调用它不会为视网膜显示器初始化正确的图像比例(imageNamed检查是否有带有后缀的文件,如果有,则从文件加载图像并设置scale=2)。只需在视网膜设备/模拟器上运行NSLog(@"%f",[UIImage imageNamed:"Default.png"].scale);和NSLog(@"%f",[UIImage imageNamed:@"Default@2x.png"].scale),您应该能看到结果。 - JakubKnejzlik
你可以随便命名它...-568@2x或者-568或者-568h... 只不过你只能选择其中一个...不能同时存在-568和-568@2x,我想这就是Ben试图说的。最终命名的规范需要你和设计师协商决定。 - LolaRun
1
@GrizzlyNetch 经过进一步测试,你是正确的。文件应该被命名为myImage-568h@2x.png,但在代码中应该写成myImage-568h.png。我已经更新了我的答案。 - Ben Clayton
这篇文章怎么样?(http://www.smartersoftware.de/wordpress/2013/02/using-imagenamed-to-pick-the-right-image-file/)我尝试了一下这种方法,但是好像并不起作用。不过我很好奇这个人是如何实现的... - Yevhen Dubinin

11

iPhone 5没有引入新的像素密度,因此您可以继续使用之前使用过的所有Retina图像。

只需要确保您的视图将填满窗口即可支持iPhone 5的新分辨率。对于大多数视图,例如tableview和scrollview,这不会带来任何问题。

而且无需为新分辨率添加额外的XIB文件,这也不受支持。

只需将Default-568h@2x.png添加到您的应用程序包中,iOS 6就会让您的应用程序占用iPhone 5中的额外空间。

所有本地控件,例如选项卡栏,都将表现得与预期相同。

如果您想在应用程序中支持iOS4.3和5.*,请确保在nib设置中(interface builder中的第一个选项卡)关闭Use Autolayout

然后,请确保正确设置视图autoresizingMask


1

编辑

注意,自iOS8起,UIScreen考虑了方向(检查高度可能会返回两个值,纵向高度或横向高度,以前仅为纵向高度),但xcassets更好,您可以在此处进行检查: 如何适应iPhone背景?

结束编辑

根据ben-clayton的答案,我制作了一个方便的类别来管理iPhone 5的图像。谢谢。

+ (UIImage *) imageForName:(NSString *)imageName
{
    NSString *result = imageName;

    CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
    BOOL isIphoneFive = ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f);

    if (isIphoneFive)
    {
        NSString *imageNameWithoutExtension = [imageName stringByDeletingPathExtension];
        NSString *extension = [imageName pathExtension];

        result = [NSString stringWithFormat:@"%@-568h.%@",imageNameWithoutExtension, extension];
    }

    return [UIImage imageNamed:result];
}

1

if ([UIScreen mainScreen].scale == 2.f && screenHeight == 568.0f) 由于浮点数在内存中的舍入误差,精确比较浮点数在任何语言中都不是一个好主意。例如,您无法保证568.0f不会被存储为567.9999999或568.0000001。使用范围更安全,或者在这种情况下,屏幕高度大于567.1f就足够了。我怀疑即使iPhone也不支持像素的分数。


1
但幸运的是,在实践中,事情并不像你所想象的那样疯狂。如果在同一平台上使用相同的编译器,只要它没有从其他各种操作中产生,我非常确定568.0在所有表示中都是相同的。想想看,在内存中声明了iPhone的高度并将其返回给您的应用程序。在那里,他们放置了568.0,然后您将其与568.0进行比较。他们使用XCode/GCC,您也使用相同的东西,那么同一编译器如何在那里放置不同的位? - RelativeGames

0

我目前正在使用这种方式来检测当前设备是否为4英寸的iPhone,并且它运行良好。祝你好运!

- (BOOL)isiPhone5{
    return ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone && [UIScreen mainScreen].bounds.size.height == 568.0);
}

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