iPhone Retina模拟器显示屏分辨率错误。

3

我正在尝试编写一个通用应用程序。不同的屏幕分辨率下,显示应该略有不同。但是当我像这样编码时:

- (void)viewDidLoad {
    SCREEN_WIDTH=[[UIScreen mainScreen] applicationFrame].size.width;
    SCREEN_HEIGHT=[[UIScreen mainScreen] applicationFrame].size.height;
    NSLog(@"w:%f h:%f",SCREEN_WIDTH,SCREEN_HEIGHT);
...
}

我在模拟器中设置为Hardware->Device->iPhone(Retina)时,输出结果为:w:320.000000 h:480.000000。此外,分辨率为这个大小的图片会在模拟器中以全屏显示。 我知道应该得到w:640.000000 h:960.000000的输出结果。 有其他人也遇到了这种情况吗?有什么解决方法或想法吗? 相关讨论请参见:这里

感谢Jonathan和Xuanweng的帮助。我已经给你们两个的答案点赞了。不过,我认为我的答案是最完整的。 - iPadDeveloper2011
3个回答

5

UIScreen 会将 Retina 显示设备的分辨率报告为非 Retina 显示设备的分辨率。这使得旧代码可以在这些屏幕上透明地运行。然而,UIScreen 暴露了一个 scale 属性,当与屏幕的边界结合使用时,可以用于确定设备的物理像素分辨率:

CGSize PhysicalPixelSizeOfScreen(UIScreen *s) {
    CGSize result = s.bounds.size;

    if ([s respondsToSelector: @selector(scale)]) {
        CGFloat scale = s.scale;
        result = CGSizeMake(result.width * scale, result.height * scale);
    }

    return result;
}

在 iPhone 4 上得到的值将为 { 640.0, 960.0 }

好的,谢谢。不过看起来如果我有一张640x960的图片,它在iPhone4上显示不正确。有没有什么“开关”我可以在某个地方“切换”以使其正常工作? - iPadDeveloper2011
谷歌是你的朋友。你应该去仔细阅读你正在做的事情。苹果公司在他们的网站上有大量的信息:http://www.google.com/search?client=safari&rls=en&q=site:developer.apple.com+retina+display&ie=UTF-8&oe=UTF-8 - Jonathan Grynspan
你认为不能使用这个系统的原因是什么?它并不难。 - Jonathan Grynspan
3
嗨,乔纳森。抱歉,我觉得你的“谷歌是你的朋友”评论很烦人。我已经阅读了你发送的前三个谷歌链接,但没有找到任何有用的信息。是的,苹果网站上有大量信息,但其中有没有任何与我的问题相关的呢? - iPadDeveloper2011
作为已经发布了多个利用Retina显示屏的应用程序,我可以说这些链接相当详尽地解释了你需要知道的内容。 - Jonathan Grynspan
显示剩余7条评论

3

这是我找到的资料。自从iOS4以来,

[[UIScreen mainScreen] applicationFrame].size.width;

[[UIScreen mainScreen] applicationFrame].size.height;

给出的是“点”的尺寸,而不是“像素”。对于其他所有内容,像素=点,但对于iPhone4来说,每个点有4个像素。普通图像在iPhone4上被缩放,因此图像中的每个像素都被映射到一个点上。这意味着iPhone4可以运行iPhone应用程序而不会有明显的变化。

添加利用iPhone更高分辨率的“高分辨率”图像的“苹果”方式是将“.png”替换为“@2x.png”作为图像文件名,并在图像中加倍像素密度(实际上只是宽度和高度)。重要的是,不要改变代码中引用图像的方式。
因此,如果你的代码中有“img.png”,如果可用,iPhone4将加载“img@2x.png”图像。

这样做的问题是,如果你想开发一个通用应用程序,并包含所有可能的屏幕分辨率/像素密度的单独图像,你的应用程序很快就会变得臃肿。

解决这个问题的常见方法是从网络上获取所有所需的图像。这将使你的二进制文件变得更小。但负面影响是会消耗你用户的网络流量,并且如果你的应用程序没有其他使用网络的原因(并且你没有在应用商店描述中说明你的应用程序需要网络),这将真正地惹恼用户。

幸运的是,我找到了另一种方法。通常情况下,当你缩放一个图像时,iPhone4会聪明地利用缩放后图像的增加像素密度。例如,你可能有:

UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100.0, 50.0)];
[indicatorButton setBackgroundImage:
   [UIImage imageNamed:@"buttonImage.png"] forState:UIControlStateNormal];

现在,如果buttonImage.png的大小是200x100,它将在所有设备上都表现得很好。同样地,如果您使用类似以下内容的方法,从一个漂亮的640x960像素的图像开始,在iPad上显示得非常好,并将其缩小到320x480像素的图像以适应较小的屏幕:
+ (UIImage*)imageWithImage:(UIImage*)image newX:(float)newX newY:(float)newY{
    CGSize newSize=CGSizeMake((CGFloat)newX, (CGFloat)newY);
    UIGraphicsBeginImageContext(newSize);
    [image drawInRect:CGRectMake(0,0,newX,newY)];
    UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

它应该在iPhone4上显示得很好。关键是不要重复缩放。例如,如果您做了这样的事情:

UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100.0, 50.0)];
    [indicatorButton setBackgroundImage:
       [Utilities imageWithImage:[UIImage imageNamed:@"buttonImage.png"] newX:100 newY:50] forState:UIControlStateNormal];

如果你不按照上述方法处理图片,那么你的像素密度就会丢失,导致在iPhone4上显示的图像会变得模糊。

最后,如果你想检测是否为iPhone4(如果使用上述技术则并不是必需的),以下代码可能会有用:

+(bool)imAnIphone4{
    return([[UIScreen mainScreen]respondsToSelector:@selector(scale)] && [UIScreen mainScreen].scale==2);
}

我正在尝试解决与您上面的解决方案有关的问题;但我不想堵塞帖子。如果您有空闲的时间,可以给我发一封快速电子邮件(您可以从我的用户资料中看到它);谢谢! - KeithComito
用户201926。我认为只有你可以在你的个人资料中看到你的电子邮件(我不能)。我可以在我的个人资料中看到我的电子邮件,但我猜你不能。无论如何,如果你的问题真正紧密相关,请分享。否则,请考虑提出自己的问题。 - iPadDeveloper2011

1
你把图片重命名为img.png@2x了吗?你还应该在代码中启用Retina显示。
即使你将模拟器设置为Retina显示,但如果代码没有启用Retina显示,则显示出来的图形将是320x480。

没有,我没有。我有一个函数,可以将图像按照给定的宽度和高度进行缩放,我只是将屏幕宽度和屏幕高度(用于我的全屏图像)传递给它。 - iPadDeveloper2011
扩展?分辨率会模糊...不建议这样做...尝试找到实际的解决方法... - xuanweng
您可以尝试使用此链接:http://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BuildTimeConfiguration/BuildTimeConfiguration.html#//apple_ref/doc/uid/TP40007072-CH7-SW24 - xuanweng
1
只是为了让你更清楚,iPad的分辨率比iPhone不同。 iPad是4:3,而iPhone是16:9。不要懒惰,创建3组图像。哈哈。 - xuanweng
哎呀呀... 三组图像会让我的应用程序变得不可理喻的大。顺便说一下,如果我的构建设置目标是iphone/ipad,在模拟器上似乎无法启动iPad模式。 - iPadDeveloper2011
显示剩余4条评论

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