【问题标题】:iOS 6 apps - how to deal with iPhone 5 screen size? [duplicate]iOS 6 应用程序 - 如何处理 iPhone 5 的屏幕尺寸? [复制]
【发布时间】:2012-09-05 23:42:37
【问题描述】:

可能重复:
How to develop or migrate apps for iPhone 5 screen resolution?

我只是想知道我们应该如何处理 iPhone 5 更大的屏幕尺寸。

由于它有更多的像素高度,像 GCRectMake 这样使用坐标的东西(并且由于视网膜/非视网膜问题只是将像素加倍)在版本之间无法无缝工作,就像我们得到 Retina 时发生的那样。

我们是否必须像 iPad 一样设计两个故事板?

我个人认为 Apple 不会要求您在每次必须绘制某些东西时检查屏幕尺寸,就像许多答案所说的那样。 iPad会发生这种情况吗?

【问题讨论】:

  • 您只需添加 4 英寸的 Default.png,您的应用程序就会立即占用 4 英寸的完整屏幕尺寸。
  • 虽然可能违反直觉,但根据 Pascal 的建议,只需添加一个视网膜(4 英寸)启动图像,即可删除应用程序视图两侧的黑色区域,从而在视网膜 4 和以前的设备。

标签: iphone ios iphone-5


【解决方案1】:

您需要添加一个 640x1136 像素的 PNG 图像 (Default-568h@2x.png) 作为项目的 4 英寸默认启动图像,它会使用额外的空间(在简单的基于表格的应用程序上不做努力,游戏将需要更多的努力)。

我创建了一个小的 UIDevice 类别来处理所有的屏幕分辨率。可以get it here,不过代码如下:

文件UIDevice+Resolutions.h:

enum {
    UIDeviceResolution_Unknown           = 0,
    UIDeviceResolution_iPhoneStandard    = 1,    // iPhone 1,3,3GS Standard Display  (320x480px)
    UIDeviceResolution_iPhoneRetina4    = 2,    // iPhone 4,4S Retina Display 3.5"  (640x960px)
    UIDeviceResolution_iPhoneRetina5     = 3,    // iPhone 5 Retina Display 4"       (640x1136px)
    UIDeviceResolution_iPadStandard      = 4,    // iPad 1,2,mini Standard Display   (1024x768px)
    UIDeviceResolution_iPadRetina        = 5     // iPad 3 Retina Display            (2048x1536px)
}; typedef NSUInteger UIDeviceResolution;

@interface UIDevice (Resolutions)

- (UIDeviceResolution)resolution;

NSString *NSStringFromResolution(UIDeviceResolution resolution);

@end

文件UIDevice+Resolutions.m:

#import "UIDevice+Resolutions.h"

@implementation UIDevice (Resolutions)

- (UIDeviceResolution)resolution
{
    UIDeviceResolution resolution = UIDeviceResolution_Unknown;
    UIScreen *mainScreen = [UIScreen mainScreen];
    CGFloat scale = ([mainScreen respondsToSelector:@selector(scale)] ? mainScreen.scale : 1.0f);
    CGFloat pixelHeight = (CGRectGetHeight(mainScreen.bounds) * scale);

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
        if (scale == 2.0f) {
            if (pixelHeight == 960.0f)
                resolution = UIDeviceResolution_iPhoneRetina4;
            else if (pixelHeight == 1136.0f)
                resolution = UIDeviceResolution_iPhoneRetina5;

        } else if (scale == 1.0f && pixelHeight == 480.0f)
            resolution = UIDeviceResolution_iPhoneStandard;

    } else {
        if (scale == 2.0f && pixelHeight == 2048.0f) {
            resolution = UIDeviceResolution_iPadRetina;

        } else if (scale == 1.0f && pixelHeight == 1024.0f) {
            resolution = UIDeviceResolution_iPadStandard;
        }
    }

    return resolution;
 }

 @end

这就是您需要使用此代码的方式。

1) 将上面的 UIDevice+Resolutions.h & UIDevice+Resolutions.m 文件添加到你的项目中

2) 将 #import "UIDevice+Resolutions.h" 行添加到您的 ViewController.m

3) 添加此代码以检查您正在处理的设备版本

int valueDevice = [[UIDevice currentDevice] resolution];

    NSLog(@"valueDevice: %d ...", valueDevice);

    if (valueDevice == 0)
    {
        //unknow device - you got me!
    }
    else if (valueDevice == 1)
    {
        //standard iphone 3GS and lower
    }
    else if (valueDevice == 2)
    {
        //iphone 4 & 4S
    }
    else if (valueDevice == 3)
    {
        //iphone 5
    }
    else if (valueDevice == 4)
    {
        //ipad 2
    }
    else if (valueDevice == 5)
    {
        //ipad 3 - retina display
    }

【讨论】:

  • 只是一些建议:1)您可能希望在报告 iPhoneTallerHiRes 之前实际测试 height==568*2 和 2)您可能还想测试宽度。然后对于未明确识别的所有内容返回UIDevice_notRecognizedRes。如果未来的 iPhone >5 或新的“新 iPad”有另一个屏幕尺寸,应该更容易适应。
  • ps。进一步考虑这种逻辑,您可能还想显式检查UIUserInterfaceIdiomPad,而不是假设!phone == pad。
  • 批准了 Evan Schoenberg 的编辑请求,以修复 iOS 4 及更高版本的标准分辨率 iPhone 上的行为。编辑后的代码位于 malcommac 的 git 存储库的一个分支中:github.com/evands/iOSUtilities/tree/main/UIDevice+Resolutions(将上下文移动到 cmets 而不是问题本身)
  • 谨慎使用 Apple 已知的类前缀。
  • @FatihArslan - 这不是您使用此功能的方式。这是不正确的“[UIDevice currentResolution] == UIDevice_iPhoneTallerHiRes”谁能告诉我如何正确使用这个函数????
【解决方案2】:

没有。

if ([[UIScreen mainScreen] bounds].size.height > 960)

在 iPhone 5 上是错误的

if ([[UIScreen mainScreen] bounds].size.height == 568)

【讨论】:

  • 为什么是 568?请给我解释一下。谢谢
  • iPhone 5的屏幕分辨率为1136x640;然而,所有尺寸都以 2 像素为单位,以与最初的 iPhone 屏幕保持一致——Apple 将 iPhone 4 中每个方向的像素数量翻了一番,但希望所有软件都可以原样运行。所以 568 是新屏幕的高度(= 1136/2)。
  • 谢谢我已经做出了改变。
  • 我喜欢这种方法,因为它是单行的,并且“硬编码”568 符合 Apple 针对设备特定启动图像的命名约定。例如Default-568h@2x.png。 Apple Docs: App Launch (Default) Images.
【解决方案3】:
@interface UIDevice (Screen)
typedef enum
{
    iPhone          = 1 << 1,
    iPhoneRetina    = 1 << 2,
    iPhone5         = 1 << 3,
    iPad            = 1 << 4,
    iPadRetina      = 1 << 5

} DeviceType;

+ (DeviceType)deviceType;
@end

.m

#import "UIDevice+Screen.h"
@implementation UIDevice (Screen)

+ (DeviceType)deviceType
{
    DeviceType thisDevice = 0;
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
    {
        thisDevice |= iPhone;
        if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
        {
            thisDevice |= iPhoneRetina;
            if ([[UIScreen mainScreen] bounds].size.height == 568)
                thisDevice |= iPhone5;
        }
    }
    else
    {
        thisDevice |= iPad;
        if ([[UIScreen mainScreen] respondsToSelector: @selector(scale)])
            thisDevice |= iPadRetina;
    }
    return thisDevice;
}

@end

这样,如果您想检测它只是 iPhone 还是 iPad(无论屏幕大小),您只需使用:

if ([UIDevice deviceType] & iPhone) 

或

if ([UIDevice deviceType] & iPad)

如果你只想检测 iPhone 5,你可以使用

if ([UIDevice deviceType] & iPhone5)

与 Malcoms 的回答相反,您需要检查它是否是 iPhone,

if ([UIDevice currentResolution] == UIDevice_iPhoneHiRes || 
    [UIDevice currentResolution] == UIDevice_iPhoneStandardRes || 
    [UIDevice currentResolution] == UIDevice_iPhoneTallerHiRes)`

这两种方式都没有一个主要优势,这只是个人喜好。

【讨论】:

  • 这对我根本不起作用,也许我遗漏了一些东西,但如果 ([UIDevice deviceType] & iPhone5) 在任何设备上为我返回 true,无论屏幕大小如何?跨度>
  • 很抱歉。我已经进行了更改。
  • 如果它是视网膜 ipod,它将返回 iPhoneRetina。如果它是一个高 ipod,它将返回 iPhone5。如果是低分辨率 iphone,它将返回 iPhone。
【解决方案4】:

我刚刚完成更新并将我的一个应用程序的 iOS 6.0 版本发送到商店。此版本向后兼容 iOS 5.0,因此我保留了 shouldAutorotateToInterfaceOrientation: 方法并添加了如下所列的新方法。

我必须做到以下几点:

自动旋转在 iOS 6 中发生了变化。在 iOS 6 中,UIViewController 的 shouldAutorotateToInterfaceOrientation: 方法已弃用。取而代之的是,您应该使用 supportedInterfaceOrientationsForWindow: 和 shouldAutorotate 方法。 因此,我添加了这些新方法(并保留旧方法以兼容 iOS 5):

- (BOOL)shouldAutorotate {
    return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskAllButUpsideDown;    
}
  • 使用视图控制器的viewWillLayoutSubviews 方法并使用视图的边界矩形调整布局。
  • 模态视图控制器:不再调用willRotateToInterfaceOrientation:duration:、
    willAnimateRotationToInterfaceOrientation:duration: 和
    didRotateFromInterfaceOrientation: 方法 任何在
    上进行全屏演示的视图控制器 本身——例如,presentViewController:animated:completion:。
  • 然后我修复了需要它的视图的自动布局。
  • 将模拟器中用于启动视图和 iTunes 商店视图的图像复制到 PhotoShop 中,并将它们导出为 png 文件。
  • 默认图片名称为:Default-568h@2x.png,尺寸为640×1136。它还允许为相同的纵向模式提供 640×1096(删除状态栏)。如果您的应用在 iPhone 上只允许横向显示,那么横向模式下也可能会提供类似的尺寸。
  • 我已经放弃了对 iOS 4 的向后兼容性。主要原因是因为已经放弃了对 armv6 代码的支持。因此,我现在能够支持的所有设备(运行 armv7)都可以升级到 iOS 5。
  • 我也在生成armv7s代码来支持iPhone 5,因此可以 在使用任何第三方框架(如 Admob 等)之前,不要使用它们 已更新。

这只是记住要在 iOS 5 和 iOS 6 中测试自动旋转,因为旋转发生了变化。

【讨论】:

  • 我的应用已经有一个可调整大小的视图,但仍然在信箱中启动。即使我将视图的宽度更改为 568,它仍然会启动 letterboxed (并压扁,以启动)!一旦我添加了 Default-568h@2x.png,它就会以正确的纵横比启动。
  • 如果你想同时支持 iOS 5 自动旋转和 ios 6 自动旋转,除了旧的自动旋转方法之外,你是否在同一个文件中包含了新的方法?
  • 安德鲁克斯,是的。您支持旧的(保留以前的方法)并添加上面的新方法。然后,在运行 iOS 5 时,它会调用旧的,而 iOS 6 会调用新的。
  • 大家好!我添加了两种自动旋转方法,但没有发生自动旋转。当我倾斜设备时,屏幕仍然是纵向的……这是什么问题?
  • 您是否在 Target -> Summary 页面上选择了轮换?
【解决方案5】:

从我今天的演示中可以看出,所有应用程序都将继续在垂直拉伸的屏幕上运行。它们将被加装信箱,或者基本上额外的 88 点高度将只是黑色。

如果你只打算支持 iOS 6+,那么一定要考虑使用 Auto Layout。它删除了所有固定的布局处理,而是使用约束来布局。没有什么是硬编码的,你的生活会变得简单得多。

但是,如果您必须支持较旧的 iOS,那么这实际上取决于您的应用程序。大多数使用标准导航栏和/或标签栏的应用程序可以简单地扩展中间的内容以用完这些额外的点。设置中心内容的自动调整大小掩码以双向扩展。

view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

它对于表格视图开箱即用效果很好,但是,如果您的应用使用像素完美的布局来显示内容,那么您最好的办法是重新设计内容,以便它可以适应不同的高度。

如果这不可能,那么剩下的唯一选择就是拥有两个 UI(iPhone 5 之前和 iPhone 5)。

如果这听起来很难看,那么您可以使用默认的信箱模型,其中额外的点/像素只显示为黑色。

编辑

要使您的应用能够在 iPhone 5 上运行,您需要添加启动器图像的视网膜版本。它应该命名为Default-568h@2x.png。而且它必须是视网膜质量 - 这里没有向后兼容性:)

您也可以从 Xcode 中选择此图像。转到目标,然后在 Summary 部分下,查找 Launch Images。图像的大小必须为 640x1136 像素。如果有帮助,请在此处找到它的屏幕截图。

【讨论】:

  • 我认为 UIActionSheet 在非高 iPhone 上的 iOS6 中被破坏,如果你使用这种方法,并且不要做任何特别的事情来修复操作表。如果我将主笔尖设置为高,那是唯一会坏的东西。
  • xcode 会自动将您的图像重命名为 Default-568h@2x.png,因此您不必自己这样命名。只需在 Photoshop 640x1136 上制作图像,然后将其拖放到项目中的指定区域即可。
  • @DaGaMs 或者,您可以将self.window.frame = [UIScreen mainScreen].bounds; 添加到-application:didFinishLaunchingWithOptions: 的顶部。
  • 如果视图包含子视图,那么视图的 autoresizesSubviews 也需要设置为 YES。
【解决方案6】:

@Pascal 对 OP 问题的评论是正确的。通过简单地添加图像,它会删除黑色边框,并且应用程序将使用整个高度。

您需要通过确定设备正在使用更大的显示器来调整任何 CGRect。 IE。如果您需要与屏幕底部对齐的内容。

我确信有一个内置方法,但我没有看到任何东西,而且很多内容仍处于 NDA 之下,因此我们在应用程序中使用的方法非常简单,是一个全局函数。将以下内容添加到您的 .pch 文件中,然后通过简单的if( is4InchRetina() ) { ... } 调用来调整您的 CGRects 等。

static BOOL is4InchRetina()
{
    if (![UIApplication sharedApplication].statusBarHidden && (int)[[UIScreen mainScreen] applicationFrame].size.height == 548 || [UIApplication sharedApplication].statusBarHidden && (int)[[UIScreen mainScreen] applicationFrame].size.height == 568)
        return YES;

    return NO;
}

【讨论】:

  • 未经测试,但是当 iPhone 有双倍大小的状态栏时,这可能存在错误。例如,在打电话时。
【解决方案7】:

由于它在高度上有更多像素,因此使用坐标的 GCRectMake 之类的东西在版本之间无法无缝工作,就像我们获得 Retina 时发生的那样。

嗯,它们确实与 Retina 显示器的工作方式相同 - 只是 CoreGraphics 坐标系中的 1 个单位将对应 2 个物理像素,但您不必/不必这样做无论如何,逻辑保持不变。 (您是否真的尝试在视网膜 iPhone 上运行您的非视网膜应用之一,曾经?)

对于实际问题:这就是为什么你不应该使用明确的 CGRectMakes 和 co...这就是为什么你有像 [[UIScreen mainScreen] applicationFrame] 这样的东西。

【讨论】:

  • “就像我们拿到 Retina 时那样。” -> 我知道他们在视网膜/非视网膜之间工作,如果我不清楚,对不起。我是说这种无缝转换不适用于 iPhone 5。
  • 你不认为苹果会比以编程方式检查屏幕大小更容易吗?
  • 是的罗伯特!嗯,这样的事情一直有效......
  • @JúlioTurollaRibeiro 更容易吗?你的意思是苹果用水晶球创造了一些工具来改变充满魔法常数的代码,这只是巧合(=直到今天仍然是相同的屏幕尺寸)?
  • @RobertVojta CGRectMake(0, 0, 320, 480); 确实适用于 Retina 显示器,就像它适用于非视网膜显示器一样。
【解决方案8】:

我认为您可以使用[UIScreen mainScreen].bounds.size.height 并为您的对象计算步长。当您计算步长时,您可以为两种分辨率设置坐标。

或者你可以得到像上面这样的高度和if(iphone5) then... else if(iphone4) then... else if(ipad)。像这样。

如果您使用故事板,那么我认为您必须为新 iPhone 创建新的。

【讨论】:

  • 这是有道理的,但正如我上面所说的,你不认为苹果会创造一些更容易的东西吗?
  • 嗯,我不知道。这与 iPhone 和 iPhone Retina 不同。此屏幕的高度像素更多,因此比例不一样。在主题演讲中显示(如果我记得的话)旧应用程序居中并且上下都有黑色带子。
  • @JúlioTurollaRibeiro “你认为 Apple 会创造更简单的东西吗”是一个主观问题。如果信息不存在,没有人可以为您回答。所以这不是一个建设性的问题。
  • 我想他们通过引入新的相对布局系统让事情变得更容易了,遗憾的是如果你想支持
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-31
  • 1970-01-01
相关资源
最近更新 更多