【问题标题】:Best way to programmatically detect iPad/iPhone hardware以编程方式检测 iPad/iPhone 硬件的最佳方法
【发布时间】:2010-05-19 00:41:29
【问题描述】:

我需要弄清楚的原因是,在 iPad 上,UIPickerView 在横向上的高度与在纵向上的高度相同。在 iPhone 上是不同的。 iPad 编程指南为 UIDevice 引入了一个“惯用语”值:

    UIDevice* thisDevice = [UIDevice currentDevice];
    if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
    {
        // iPad
    }
    else
    {
        // iPhone
    }

当您使用 iPad (3.2) 而不是 iPhone (3.1.3) 时可以正常工作 - 所以看起来还需要一个 ifdef 来有条件地编译该检查,例如:

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30200
        UIDevice* thisDevice = [UIDevice currentDevice];
        if(thisDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad)
        {
            // etc.
        }
#endif

对我来说,这开始看起来很笨拙。有什么更好的方法?

【问题讨论】:

    标签: iphone orientation ipad


    【解决方案1】:

    在运行时检查(您的第一种方式)与编译时的#if 完全不同。预处理器指令不会为您提供通用应用程序。

    首选方式是使用苹果的宏:

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
    {
         // The device is an iPad running iPhone 3.2 or later.
    }
    else
    {
         // The device is an iPhone or iPod touch.
    }
    

    使用 3.2 作为基础 SDK(因为宏未在 3.2 之前定义),您可以针对之前的操作系统版本使其在 iPhone 上运行。

    【讨论】:

      【解决方案2】:

      我现在(并且在这么晚的日期)回答这个问题,因为许多现有的答案都已经很老了,根据 Apple 的当前文档(iOS 8.1,2015),投票最多的答案实际上似乎是错误的!

      为了证明我的观点,这是来自 Apple 头文件的注释(始终查看 Apple 源代码和头文件):

      /*The UI_USER_INTERFACE_IDIOM() macro is provided for use when
        deploying to a version of the iOS less than 3.2. If the earliest
        version of iPhone/iOS that you will be deploying for is 3.2 or
        greater, you may use -[UIDevice userInterfaceIdiom] directly.*/
      

      因此,目前APPLE推荐检测iPhone与iPad的方法如下:

      1) (自 iOS 13 起已弃用)在 iOS PRIOR 到 3.2 的版本上,使用 Apple 提供的宏:

      // for iPhone use UIUserInterfaceIdiomPhone
      if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
      

      2) 在 iOS 3.2 或更高版本上,使用 [UIDevice currentDevice] 上的属性:

      // for iPhone use UIUserInterfaceIdiomPhone
      if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
      

      【讨论】:

      • 如果你跳转到 UI_USER_INTERFACE_IDIOM() 的定义,你会看到它使用了 [[UIDevice currentDevice] userInterfaceIdiom] 属性。 static inline UIUserInterfaceIdiom UI_USER_INTERFACE_IDIOM() { return ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? [[UIDevice currentDevice] userInterfaceIdiom] : UIUserInterfaceIdiomPhone);
      • 啊!这就是我在他们的文档中找到我在这个答案中引用的评论的方式:)
      • 我的意思是即使在 iOS 3.2 或更高版本中你也可以使用UI_USER_INTERFACE_IDIOM(),因为它与[UIDevice currentDevice].userInterfaceIdiom] 相同。对吗?
      • 优化...不是真的。更清楚你实际使用的是什么。
      • UI_USER_INTERFACE_IDIOM() 在 IOS 13 中已弃用,请使用第二个选项。
      【解决方案3】:

      我喜欢我的isPad() 功能。相同的代码,但不要放在视线之外,而且只在一个地方。

      【讨论】:

        【解决方案4】:

        我的解决方案(适用于 3.2+):

        #define IS_IPHONE (!IS_IPAD)
        #define IS_IPAD (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone)
        

        那么,

        if (IS_IPAD)
            // do something
        

        if (IS_IPHONE)
            // do something else
        

        【讨论】:

        • 这是一个不错的选择,我们可以#define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 这也是我们可以做对的...再次感谢 lewisanderson
        • 这不是最好的逻辑,因为在大多数情况下 iPod 确实应该与 iPhone 组合在一起,而不是 iPad。
        【解决方案5】:

        在 Swift 中使用 userInterfaceIdiom 实例属性作为 -

        if UIDevice.current.userInterfaceIdiom == .phone {
             print("iPhone")
         }
        

        & 对于其他设备 -

          switch UIDevice.current.userInterfaceIdiom {
            case .pad:
                print("iPad")
            case .phone:
                print("iPhone")
            case .tv:
                print("TV")
            case .carPlay:
                print("carPlay")
            default: break;
          }
        

        【讨论】:

          【解决方案6】:

          将此方法放在您的 App Delegate 中,以便您可以使用 [[[UIApplication sharedApplication] delegate] isPad] 在任何地方调用它]

          -(BOOL)isPad
          {
              BOOL isPad;
              NSRange range = [[[UIDevice currentDevice] model] rangeOfString:@"iPad"];
              if(range.location==NSNotFound)
              {
                  isPad=NO;
          
          
              }
              else {
                  isPad=YES;
              }
          
              return isPad;
          }
          

          【讨论】:

          • 第一个:UI_USER_INTERFACE_IDIOM() 方法是要走的路。第二:您的设备型号不会改变,因此请为自己节省一些 CPU 周期并将结果缓存在静态变量中并使用dispatch_once
          • 在您的应用程序中的某处放置一个新函数会使所有调用者依赖于您放入的任何类。简单地调用其中一个 API 函数似乎更好。
          【解决方案7】:

          如果您使用的是不向后兼容的功能,我发现对我来说最好的方法是在预编译的标头中创建一个#define。示例:

          #if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2
          #define USING_4_X
          #endif
          

          然后在你的代码中,你可以这样做:

          BOOL exists = NO;
          #ifdef USING_4_X        
          exists = [SomeObject someMethod:[url lastPathComponent]];
          #else
          exists = [SomeObject someMethod:[[url path] lastPathComponent]];
          #endif
          

          【讨论】:

          • 您的解决方案将导致您需要拥有两个版本的二进制文件。
          【解决方案8】:

          如果 1-您已经将应用程序安装到您的设备中, 2-您将其构建设置更改为“通用”应用程序, 3- 将应用程序安装到您的设备上预先存在的应用程序之上(不删除之前的应用程序)

          您可能会发现此处提供的用于检测 iPhone/iPad 的解决方案不起作用。首先,删除“仅”用于 iPad/iPhone 的应用程序并将其重新安装到您的设备上。

          【讨论】:

            【解决方案9】:
            BOOL isIpad()
            {
                if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
                    return YES;
                }
                return NO;
            }
            

            【讨论】:

              【解决方案10】:
              extension UIDevice {
              
                 var isIPad: Bool {
                    return UIDevice.current.userInterfaceIdiom == .pad
                 }
              }
              

              【讨论】:

              • a)将其设为静态变量(因为您不是真正访问 self,而是访问任何实例是 .current)或 b)将 UIDevice.current 替换为自己?
              猜你喜欢
              • 1970-01-01
              • 2012-10-14
              • 2020-05-23
              • 1970-01-01
              • 2011-04-12
              • 1970-01-01
              • 2011-01-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多