32

Apple 建议使用以下代码来检测是否在 iPad 或 iPhone/iPod Touch 上运行:

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
  // The device is an iPad running iPhone 3.2 or later.
  // [for example, load appropriate iPad nib file]
}
else {
  // The device is an iPhone or iPod touch.
  // [for example, load appropriate iPhone nib file]
}

问题是 UI_USER_INTERFACE_IDIOM() 和 UIUserInterfaceIdiomPad 没有在 3.2 之前的 SDK 中定义。这似乎完全违背了这种功能的目的。它们只能在 iPhone OS 3.2 上编译和运行(iPhone OS 3.2 只能在 iPad 上运行)。因此,如果您可以使用 UI_USER_INTERFACE_IDIOM(),结果将始终指示 iPad。

如果您包含此代码并以 OS 3.1.3(最新的 iPhone/iPod Touch OS)为目标来测试您的 iPhone 绑定的通用应用程序代码,您将收到编译器错误,因为符号未在 3.1.3 或更早版本中定义,为 iPhone 模拟器 3.1.3 编译时。

如果这是 Apple 推荐的运行时设备检测方法,我做错了什么?有没有人成功使用这种方法进行设备检测?

4

8 回答 8

24

我这样做是为了让代码在 3.1.3 和 3.2 中编译:

BOOL iPad = NO;
#ifdef UI_USER_INTERFACE_IDIOM
iPad = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#endif
if (iPad) {
// iPad specific code here
} else {
// iPhone/iPod specific code here
}

我还在这里写了一篇关于它的快速博客文章:http: //www.programbles.com/2010/04/03/compiling-conditional-code-in-universal-iphone-ipad-applications/

于 2010-04-09T15:41:47.447 回答
14

这就是我使用的:

- (BOOL) amIAnIPad {
    #if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 30200)
        if ([[UIDevice currentDevice] respondsToSelector: @selector(userInterfaceIdiom)])
            return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad);
    #endif
    return NO;
}

这有条件地编译,因此您仍然可以为 3.0 sim 构建。然后它检查 UIDevice 类是否响应选择器。如果其中任何一个失败,它就不是 iPad。

于 2010-04-05T03:51:29.553 回答
7

如果这是 Apple 推荐的运行时 设备检测方法,我做错了什么?有没有人成功使用这种方法进行设备检测?

这是运行时检测的解决方案:

#define isIPhone (![[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] || [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)

之后,您可以轻松地在代码中的任何位置对其进行测试:

if (isIPhone) { ... }

这和使用#if / #ifdef 的区别在于这是运行时测试,而#if 是编译时测试。

我认为运行时测试更好,因为在这种情况下,您可以为任何操作系统版本使用一个可精确的。如果您使用编译时检查,则需要为不同的操作系统版本生成不同的可执行文件。

如果您的问题是编译时错误,您只需针对最新版本的 SDK 进行编译(另请参阅如何在 iOS 中访问弱链接框架?)。

于 2012-01-05T19:32:21.407 回答
5

我相信答案就是不要尝试在 iPhone模拟器3.1.3 或更早版本上运行代码。始终使用 3.2 SDK 进行编译。iPhone 模拟器 3.2 将为您提供 iPad 模拟器,或者为 iPhone 设备 3.2 编译并将应用程序放在手机上进行测试。

无法针对 3.2 SDK 进行编译并使用 3.1.3 或更早版本的模拟器。

于 2010-04-05T04:13:56.687 回答
5

而不是我使用的任何基于编译器的东西:

- (BOOL)deviceIsAnIPad {
if ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)])
    //We can test if it's an iPad. Running iOS3.2+
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
        return YES; //is an iPad
    else 
        return NO; //is an iPhone
else 
    return NO; //does not respond to selector, therefore must be < iOS3.2, therefore is an iPhone
}
于 2012-04-17T07:32:43.067 回答
2

声明使用这个

#ifdef UI_USER_INTERFACE_IDIOM
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
#else
#define IS_IPAD false
#endif

然后使用检查如下

#define DetailLabel_PosX (IS_IPAD ? 200 : 160)

还有一些用于检查 iphone 5 的定义

#define IS_IPHONE5 (([[UIScreen mainScreen] bounds].size.height-568)?NO:YES)
#define IOS_OLDER_THAN_6 ([[[UIDevice currentDevice] systemVersion] floatValue] < 6.0 )
#define IOS_NEWER_OR_EQUAL_TO_6 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0 )
于 2012-07-26T07:20:44.707 回答
0

这似乎完全违背了这种功能的目的。它们只能在 iPhone OS 3.2 上编译和运行(iPhone OS 3.2 只能在 iPad 上运行)。因此,如果您可以使用 UI_USER_INTERFACE_IDIOM(),结果将始终指示 iPad。

这是完全不正确的。它可以在 3.2 的 Base SDK 上编译,但如果您适当地设置部署目标,它可以在任何操作系统上运行。

于 2011-03-12T00:31:01.200 回答
0

UI_USER_INTERFACE_IDIOM() 和 UIUserInterfaceIdiomPad 可以在 iOS3.2 及更高版本上使用,重要的部分是“向上”。当然。iOS3.2 仅适用于 iPad,但 iOS4.0 及更高版本可在 iPhone 和 iPad 上运行,因此检查并不像您想象的那样毫无意义。

于 2011-05-28T23:31:36.947 回答