iPhone Retina 模拟器的屏幕分辨率错误

发布于 2024-10-13 07:23:01 字数 671 浏览 6 评论 0原文

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

- (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);
...
}

即使模拟器设置为
,我也会得到输出:w:320.000000 h:480.000000 硬件 -> 设备 -> iPhone (Retina)
此外,具有此分辨率的图像在模拟器中显示为全屏图像。
我知道我应该得到 w:640.000000 h:960.000000
对于其他人来说也是这样吗?以及为什么/如何解决的任何想法? 请参阅相关主题:此处

I'm trying to write a Universal Application. The display should be slightly different for different screen resolutions. But when I code like this:

- (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);
...
}

I get output: w:320.000000 h:480.000000 even when the simulator is set to
Hardware->Device->iPhone (Retina)
Furthermore, images with this resolution display as full-screen images in the simulator.
I understand I should be getting w:640.000000 h:960.000000.
Is it like this for anyone else? And any ideas why/how to fix?
See the related thread: here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猫七 2024-10-20 07:23:01

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 }

UIScreen will always report the resolution of a Retina Display device as that of a non-Retina Display device. This allows old code to run transparently on such screens. However, UIScreen exposes a scale property which, when combined with the bounds of the screen, can be used to determine the physical pixel resolution of a device:

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;
}

The resulting value on an iPhone 4 would be { 640.0, 960.0 }.

回心转意 2024-10-20 07:23:01

这是我发现的。从iOS4开始,

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

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

以“点”而不是“像素”为单位给出测量值。对于其他一切,像素=点,但对于 iPhone4,每个点有 4 个像素。普通图像在 iPhone4 中会进行缩放,因此图像中的每个像素都会映射到一个点。这意味着iPhone4可以运行iPhone应用程序而不会发生明显的变化。

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

这样做的问题是,如果您尝试开发通用应用程序,并为所有不同可能的屏幕分辨率/像素密度包含单独的图像,您的应用程序将很快变得臃肿。

此问题的常见解决方案是从“网络”中提取所有所需的图像。这将使您的二进制文件变得又小又漂亮。不利的一面是,这会占用用户的互联网配额,并且会真正惹恼没有 wifi 的用户 - 特别是如果您的应用没有其他理由使用“网络”(并且您没有在应用程序商店描述中说您的应用程序需要“网络”)。

幸运的是,我找到了另一种方法。通常,当您缩小图像时,iPhone4 足够聪明,能够利用缩放图像增加的像素密度。例如,您可能有:

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

现在,如果 buttonImage.png 是 200x100,那么它在所有内容上都会表现得非常好。同样,如果您从一个在 iPad 上显示效果很好的 640x960(像素)图像开始,然后将其缩小到较小屏幕上的 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);
}

Here is what I've found out. Since iOS4,

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

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

give measurements in "points", not "pixels". For everything else, pixels=points, but for the iPhone4, each point has 4 pixels. Normal images are scaled in the iPhone4, so each pixel in the image is mapped onto a point. This means that the iPhone4 can run iPhone apps without a noticeable change.

The "apple" way to add "hi-res" images that take advantage of the iPhone's greater resolution is to replace ".png" with "@2x.png" in the image file name, and double the pixel density (effectively, just the width&height) in the image. Importantly, don't change the way the image is referred to in your code.
So if you have "img.png" in your code, iPhone4 will load the "[email protected]" image if it is available.

The problem with this is that, if you are trying to develop a Universal app, and include separate images for all the different possible screen resolutions/pixel densities, your app will get bloated pretty quick.

A common solution to this problem is to pull all the required images of the 'net. This will make your binary nice and small. On the negative side, this will eat into your user's internet quota, and it will really annoy users who don't have wifi--especially if your app has no other reason to use the 'net (and you don't say your app needs the 'net in your app store description).

Fortunately, I have found another way. Often, when you scale down an image, the iPhone4 is clever enough to utilise the increased pixel density of the scaled image. For example, you might have:

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

Now if buttonImage.png is 200x100, it will be perfectly well behaved on everything. Similarly, if you start with a nice 640x960 (pixel) image that displays quite nicely on the iPad and you scale it down to a 320x480 image for smaller screens, using something like:

+ (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;
}

It should display quite nicely on the iPhone4. The trick is not to double-up on your scaling. For example, if you do something like:

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];

Then you'll have lost your pixel density and your image will look all "pixely" on the iPhone4.

Finally, if you want to detect if you are an iPhone4 (not really necessary if you use the above technique), the following code may be useful:

+(bool)imAnIphone4{
    return([[UIScreen mainScreen]respondsToSelector:@selector(scale)] && [UIScreen mainScreen].scale==2);
}
帅气称霸 2024-10-20 07:23:01

您是否将图像重命名为 img.png@2x ?并且您应该在代码中启用视网膜显示。

即使您将模拟器设置为视网膜显示,但代码未启用视网膜显示,显示的图形也将是 320x480。

Did you rename the images as img.png@2x? And you should enable retina display in your code.

Even if you set simulator to retina display BUT the code is not retina display enabled, the graphics displayed out would be 320x480.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文