【问题标题】:#if check (preprocessor macro) to differentiate between iPhone and iPad#if 检查(预处理器宏)以区分 iPhone 和 iPad
【发布时间】:2010-09-12 23:47:22
【问题描述】:

是否有我可以检查的构建预处理器宏,使用 #if 或 #ifdef 来确定我当前的 Xcode 项目是为 iPhone 还是 iPad 构建的?

编辑

正如几个答案所指出的,应用程序通常是通用的,并且相同的二进制文件可以在两种设备上运行。这些非常相似的设备之间的条件行为应该在运行时而不是编译时解决。

【问题讨论】:

    标签: objective-c iphone c-preprocessor


    【解决方案1】:

    本博客评论区的一些想法

    http://greensopinion.blogspot.com/2010/04/from-iphone-to-ipad-creating-universal.html

    主要使用

    UI_USER_INTERFACE_IDIOM()
    

    如:

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

    【讨论】:

    • 这实际上是在 wwdc 的苹果讲座中提出的。
    • 为什么要使用宏?没有人支持低于 3.2 的 iOS,所以UI_USER_INTERFACE_IDIOM 的优势是没有。
    • 这个问答来自2010年。
    • @LouFranco 对不起,下次我会检查日期。
    【解决方案2】:
    NSString *deviceType = [UIDevice currentDevice].model;
    
    if([deviceType isEqualToString:@"iPhone"]) {
        //iPhone
    }
    else if([deviceType isEqualToString:@"iPod touch"]) {
        //iPod Touch
    }
    else {
        //iPad
    }
    

    就我而言,您不能使用 #if 或 #ifdef 来执行此操作,但它受到支持,因为 Obj-C 是 C 的严格超集。

    相关: Determine device (iPhone, iPod Touch) with iPhone SDK

    【讨论】:

    • 这就是我所害怕的,因为它们必须运行相同的应用程序。
    • 感谢您的帮助。我想我可以想到一个我可以设置的配置,它基于此创建一个#define。
    • 您不能对“通用二进制文件”进行编译时检查,因为它是为两者构建的。如果您构建单独的 iPad 和 iPhone 应用程序,那么有很多方法,包括为不同的目标定义自己的编译器宏。
    • 这不安全!明天Apple更改字符串并且您的应用程序停止正常工作。 UIDevice 中的 userInterfaceIdiom 属性是最安全的方法。
    • 不安全。您不应该比较字符串,而是使用 UIDevice API。
    【解决方案3】:

    无法确定您的应用是为 iPhone 还是 iPad 构建的。 预处理器 #if 指令在构建过程中被解析。一旦您的应用程序被构建并标记为 Universal,它必须在两个设备上都能正常运行。在构建过程中,没有人知道它稍后会安装在哪里,并且可以在两者上安装一个构建。

    但是您可能想要执行以下操作之一:

    1. 检测设备型号 在运行时

      为此,请使用[[UIDevice currentDevice] model] 并与iPhoneiPod touchiPad 字符串进行比较。即使在 iPad 上以兼容模式运行时(仅适用于 iPhone 的应用程序),这也会为您返回正确的设备。这对于使用情况分析很有用。

    2. 检测用户界面惯用语 在运行时

      这是每个人在为 iPhone 和 iPad 提供不同内容时都会检查的内容。使用[[UIDevice currentDevice] userInterfaceIdiom] 并与UIUserInterfaceIdiomPhoneUIUserInterfaceIdiomPad 进行比较。您可能想要制作这样的便捷方法:

      @implementation UIDevice (UserInterfaceIdiom)
      
      - (BOOL)iPhone {
          return (self.userInterfaceIdiom == UIUserInterfaceIdiomPhone);
      }
      + (BOOL)iPhone {
          return [[UIDevice currentDevice] iPhone];
      }
      
      - (BOOL)iPad {
          return (self.userInterfaceIdiom == UIUserInterfaceIdiomPad);
      }
      + (BOOL)iPad {
          return [[UIDevice currentDevice] iPad];
      }
      
      @end
      

      那么你可以使用:

      if ([[UIDevice currentDevice] iPhone]) { }
      // or
      if ([UIDevice iPhone]) { }
      // or
      if (UIDevice.iPhone) { }
      

    【讨论】:

    • 两年多前我问过这个问题,我现在明白什么时候应该使用运行时与编译时检查。感谢你的回答!我相信它会帮助其他人。
    • 哦,日期!所以我希望它会对某人有所帮助。
    【解决方案4】:

    快速更新:

    无法使用预处理器。将全局函数设为

    func IS_IPAD() -> Bool { 
    ( return (UIDevice.respondsToSelector(Selector("userInterfaceIdiom"))) && (UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad) )}
    

    【讨论】:

    • 如 UI_USER_INTERFACE_IDIOM() 宏中所述,如果您为低于 3.2 的 iOS 版本进行部署,则只需检查选择器。使用 Swift 可以排除这种情况。 ;)
    【解决方案5】:

    我对 AppleTV 4 使用以下代码,因为 UIUserInterfaceIdiomUnspecified,似乎不起作用,也找不到任何其他枚举:

    #ifdef TARGET_OS_IOS
    CGSize result = [[UIScreen mainScreen] bounds].size;
        if(result.width == 1920) {
            NSLog(@"tvOS");
        }
    #endif
    

    我曾经在黑暗时代之前将它用于 iPad 等,在帝国-OB1 之前,哈哈晚安。但是您可以将这种类似的技术用于您知道的其他屏幕尺寸。

    【讨论】:

      猜你喜欢
      • 2012-09-28
      • 1970-01-01
      • 1970-01-01
      • 2012-08-11
      • 2017-04-19
      • 1970-01-01
      • 2013-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多