如何在iOS 8.3中检测设备是否为iPad?

7
我们将SDK更新到iOS 8.3,结果我们的iPad检测方法突然失效了:
+ (BOOL) isiPad
{
#ifdef UI_USER_INTERFACE_IDIOM
    return UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
#endif
    return NO;
}
ifdef代码块永远不会进入,因此return NO;总是运行。 如何检测设备是否为iPad而不使用UI_USER_INTERFACE_IDIOM()
我正在使用:
  • Xcode 6.3(6D570)
  • iOS 8.2(12D508) - 使用iOS 8.3编译器编译
  • 部署:目标设备系列:iPhone / iPad
  • Mac OS X:Yosemite(10.10.3)
  • Mac:MacBook Pro(MacBookPro11,3)

1
右键单击 UI_USER_INTERFACE_IDIOM,然后选择“查找定义”。它显示了什么? - trojanfoe
那看起来还不错。UIKit文档也显示它仍然有效。我猜你需要展示更多的代码(即使用该方法的代码)。 - trojanfoe
@rmaddy即使如此,#ifdef UI_USER_INTERFACE_IDIOM不应该是true吗? - Ky -
实际上文档中写着“仅支持 iOS 8.3 及以上版本”,但是 userInterfaceIdiom 的文档中却写着“仅支持 iOS 3.2 及以上版本”。我会按照 Apple 的指示使用 userInterfaceIdiom - trojanfoe
当我在iPad上使用#ifdef UI_USER_INTERFACE_IDIOM时,它总是返回0。但是当我使用UI_USER_INTERFACE_IDIOM本身时,它返回正确的值,即1。你知道这是为什么吗?:( - KarenAnne
显示剩余10条评论
1个回答

13

8.2版本中,UserInterfaceIdiom()已经:


#define UI_USER_INTERFACE_IDIOM() ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? [[UIDevice currentDevice] userInterfaceIdiom] : UIUserInterfaceIdiomPhone)

8.3 中,UserInterfaceIdiom()

static inline UIUserInterfaceIdiom UI_USER_INTERFACE_IDIOM() {
    return ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ?
            [[UIDevice currentDevice] userInterfaceIdiom] :
            UIUserInterfaceIdiomPhone);
}

所以在 8.3 中,#ifdef UI_USER_INTERFACE_IDIOM 始终为 false。

请注意标题中的内容:

在部署到 iOS 版本低于 3.2 的情况下,提供了 UI_USER_INTERFACE_IDIOM() 函数供使用。如果您要部署的最早版本的 iPhone/iOS 是 3.2 或更高版本,则可以直接使用 -[UIDevice userInterfaceIdiom]。

因此建议您重构为:

+ (BOOL) isiPad
{
    static BOOL isIPad = NO;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        isIPad = [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad;
    });
    return isIPad;
}

那4行代码只会运行一次,是吗? - Ky -
1
是的,这就是dispatch_once函数所实现的目标 :-) - Warren Burton
好的。使用类似 #define _isiPad [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad 这样的东西,然后只返回 _isiPad 也可以工作吗? - Ky -
2
没有必要只计算一次这个值。只计算一次更便宜,因为iPad通常不会在运行时变成iPhone。所以,如果适合您的目的,请使用#define。引用的文档告诉您确切的真相。如果您希望自己阅读,请在Xcode中Cmd-Click UI_USER_INTERFACE_IDIOM()以进入头文件。 - Warren Burton
嗨@WarrenBurton,你能解释一下为什么#ifdef UI_USER_INTERFACE_IDIOM在8.3中不起作用吗?谢谢。我无法理解。:( - KarenAnne
1
因为很可能要使其与Swift一起工作,所以它已成为内联函数。对于您使用#ifdef进行的查询的答案“它是否定义为C预处理器宏”,是不。 - Warren Burton

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