iPad Pro 设备检测

21

我正在尝试检测iPad Pro设备,尝试猜测其高度:

NSLog(@"%f",self.view.frame.size.height);

但它返回了1024!与iPad非Retina设备相同。有什么建议吗?

我需要使用以下代码行来精确指定iPad Pro的某些代码:

#define iPadPro ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad && [UIScreen mainScreen].bounds.size.height == 2732)

...而且代码必须在iOS模拟器上检测到iPad Pro!

谢谢。

编辑:有些人建议使用LunchScreen,但当我使用它时会出现这种情况(缩小):

enter image description here

4
你不能不使用启动屏。要支持iPad Pro,必须有一个能够缩放到其更大尺寸的启动屏。 - rmaddy
3
你没有在听。为了让任何一个应用程序支持iPad Pro,你的应用程序必须使用启动屏幕(LaunchScreen),不能使用启动图像。一旦你添加了适当的启动屏幕(它将用于运行iOS 8.0及更高版本的所有设备),那么你的应用程序就不会在iPad Pro上被缩放。然后你可以根据需要使用你问题中的代码。 - rmaddy
1
你将视图框架记录在哪里? [UIScreen mainScreen].bounds 返回什么? - rmaddy
有没有检查新款 iPad Pro 9.7" 的想法?其像 iPad Air 2 一样拥有相同的像素。 - derdida
@rmaddy 你好,偶然看到了这个问题。我也遇到了同样的问题,我正在使用LaunchScreen,但在iPad Pro上运行时,我遇到了与上面问题中概述的相同的框架问题。 - Mike Simz
显示剩余4条评论
11个回答

15

特别感谢 @rmaddy

检测屏幕尺寸的正确方法是:

NSLog(@"%f",[UIScreen mainScreen].bounds.size.height);

如果您的应用程序在 竖屏 模式下运行,则可以使用以下代码来检测iPad Pro:

Translated:

现在如果你的应用程序在竖屏模式下运行,你可以简单地使用这段代码来检测 iPad Pro :

#define iPadPro ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad && [UIScreen mainScreen].bounds.size.height == 1366)

不要忘记使用LaunchScreen,否则应用程序将无法利用iPad Pro更大的屏幕


4
不要忘记需要使用启动画面,否则应用程序无法发挥iPad Pro较大屏幕的优势。 - rmaddy
1
iPad Pro现在有9.7英寸,这个失败了。 - jjxtra
@jjxtra,这并不失败,因为9.7英寸的高度仍然保持在1366。 - GeneCode
1
@GeneCode 不要按照这个链接:http://m.gsmarena.com/apple_ipad_pro_9_7-7984.php - jjxtra
有趣。谢谢你提供的信息。 - GeneCode
1
以上解决方案在iPad pro 12.9模拟器中不起作用。 - user2552751

9
检测 iPad Pro 12.9 英寸的设备方向。
#define iPadPro12 (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad && UIScreen.mainScreen.nativeBounds.size.height == 2732) 

1
以上解决方案在iPad Pro 12.9模拟器中不起作用。执行命令:po [[UIScreen mainScreen] nativeBounds].size.height -> 输出2048,执行命令:po [[UIScreen mainScreen] bounds].size.height -> 输出1024。 - user2552751

5

这里是一个可以在任何设备方向下工作的检查方法:

- (BOOL)isIpadPro
{
    UIScreen *mainScreen = [UIScreen mainScreen];
    CGFloat width = mainScreen.nativeBounds.size.width / mainScreen.nativeScale;
    CGFloat height = mainScreen.nativeBounds.size.height / mainScreen.nativeScale;
    BOOL isIpad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
    BOOL hasIPadProWidth = fabs(width - 1024.f) < DBL_EPSILON;
    BOOL hasIPadProHeight = fabs(height - 1366.f) < DBL_EPSILON;
    return isIpad && hasIPadProHeight && hasIPadProWidth;
}

请注意,此操作仅适用于iOS8及以上版本。

对于最后两个布尔值,第一个不应该是 hasIPadProWidth,第二个是 hasIPadProHeight 吗? - Rolleric
对我来说运行良好。我将其作为UIDevice的类方法放入了一个类别中。 - vikzilla

5

感谢 @Mc.Lover

针对竖屏横屏方向的一些更新:

if (([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad && ([UIScreen mainScreen].bounds.size.height == 1366 || [UIScreen mainScreen].bounds.size.width == 1366))) {
//iPad Pro
}

5

Swift 3+的固定解决方案

有两种解决方案,第一种是我在项目中使用的,您可以使用其中任意一种。

1- 使用宏

2- 使用扩展

使用宏

#define iPadPro129 (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad && 
                                  UIScreen.mainScreen.nativeBounds.size.height == 2732) 

#define iPadPro105 (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad && 
                                  UIScreen.mainScreen.nativeBounds.size.height == 2224) 

使用扩展功能

extension UIDevice {

    // for ipad pro 12.9 device
     public var isPadPro129: Bool {
         if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad 
             && UIScreen.main.nativeBounds.size.height == 2732) {
              return true
         }
         return false
     }



  // for ipad pro 10.5 device
     public var isPadPro105: Bool {
         if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad 
             && UIScreen.main. nativeBounds.size.height == 2224) {
              return true
         }
         return false
     }

}

4

D1mers0n的解决方案的Swift版本。

func isIpadPro() -> Bool
{
    if (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad &&
        (UIScreen.mainScreen().bounds.size.height == 1366 || UIScreen.mainScreen().bounds.size.width == 1366)) {
        return true
    }
    return false
}

4

遵循Swift3标准/惯例,更好的方法是:

extension UIDevice {

     public var isiPadPro12: Bool {
         if UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad 
             && (UIScreen.main.bounds.size.height == 1366 || UIScreen.main.bounds.size.width == 1366) {
              return true
         }
         return false
     }

}

将以下内容添加到 UIDevice 的扩展中,这样你就可以调用这个整洁的方法:UIDevice.current.isiPadPro12。有一天,苹果终将为我们提供一个枚举(enum)值!

2

我用宏定义在Objective-C中实现了解决方案:

最初的回答:

define IS_IPAD_DEVICE   ([(NSString *)[UIDevice currentDevice].model hasPrefix:@"iPad"])    
define IS_IPAD_IDIOM    (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)    
define IS_IPAD          (IS_IPAD_DEVICE || IS_IPAD_IDIOM)    
define IS_PORTRAIT                              UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation])    
define IS_LANDSCAPE                             UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])    
define IS_IPAD_PRO_12_9  (IS_IPAD && ((IS_PORTRAIT && [[UIScreen mainScreen] nativeBounds].size.height == 2732.0) || (IS_LANDSCAPE && [[UIScreen mainScreen] nativeBounds].size.height == 2048.0)))    
define IS_IPAD_PRO_11    (IS_IPAD && ((IS_PORTRAIT && [[UIScreen mainScreen] nativeBounds].size.height == 2388.0) || (IS_LANDSCAPE && [[UIScreen mainScreen] nativeBounds].size.height == 1668.0)))    
define IS_IPAD_PRO_10_5  (IS_IPAD && ((IS_PORTRAIT && [[UIScreen mainScreen] nativeBounds].size.height == 2224.0) || (IS_LANDSCAPE && [[UIScreen mainScreen] nativeBounds].size.height == 1668.0)))    
define IS_IPAD_OR_MINI   (IS_IPAD && ((IS_PORTRAIT && [[UIScreen mainScreen] nativeBounds].size.height == 2048.0) || (IS_LANDSCAPE && [[UIScreen mainScreen] nativeBounds].size.height == 1536.0)))

1
这并不是最好的长期解决方案,但对于今天而言它可行...
获取设备的硬件字符串...
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = malloc(size);
sysctlbyname("hw.machine", machine, &size, NULL, 0);

NSString *hardwareString = [NSString stringWithCString:machine encoding:NSUTF8StringEncoding];
free(machine);

将硬件字符串与这些硬件字符串进行比较:
if ([hardwareString isEqualToString:@"iPad6,7"] || [hardwareString isEqualToString:@"iPad6,8"]) {
    // iPad Pro
}

如果您需要,我有一个包装所有这些内容的类可以发送给您。我从来没有真正地将其打磨得足够好以使其成为一个Pod,但是如果需要的话我确实有它。

3
不要这样做。有适当的方法来检测屏幕大小。 - rmaddy
2
我认为问题是如何检测设备类型而不是屏幕尺寸。 - Dan Loughney
2
但是检测设备类型的唯一原因(至少对于OP的问题)是根据屏幕大小以不同的方式处理事情。 - rmaddy
1
我不是这样阅读它的。听起来像是Mc.Lover想要在iPad Pro上做一些特定的事情,使用屏幕尺寸作为区分iPad和Pro的指标。无论如何,如果你需要让你的产品上市,我的方法今天可以解决问题,但每次苹果发布新型号时都需要进行维护--硬件字符串需要更新。 - Dan Loughney
4
这是不使用这个答案的另一个原因。它在模拟器中无法正常工作。为iPad Pro(启动画面)添加适当的支持,原始代码就可以按预期工作了。 - rmaddy
显示剩余3条评论

0

Justin Domnitz的D1mers0n解决方案的Swift 3版本:

func isIpadPro12() -> Bool
    {
        if (UIDevice.current.userInterfaceIdiom == UIUserInterfaceIdiom.pad 
        && (UIScreen.main.bounds.size.height == 1366 || UIScreen.main.bounds.size.width == 1366)) {
            return true
        }
        return false
    }

最好作为一个变量而不是一个函数,检查一下我遵循的Swift3实践方法。 - RichAppz

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