【问题标题】:Check iOS version at runtime?在运行时检查 iOS 版本?
【发布时间】:2010-10-05 10:49:51
【问题描述】:

这是我上一个问题的后续。我正在使用beginAnimations:context: 设置一个动画块来为一些 UITextLabels 设置动画。但是我注意到文档中说:“在 iOS 4.0 及更高版本中不鼓励使用此方法。您应该改用基于块的动画方法。”

我的问题是我很想使用 animateWithDuration:animations:(在 iOS 4.0 及更高版本中可用)但不想排除使用 iOS 3.0 的人。有没有办法在运行时检查设备的 iOS 版本,以便我可以决定使用哪个语句?

【问题讨论】:

标签: iphone objective-c cocoa-touch


【解决方案1】:

为将来需要帮助的人提供更简单的解决方案:

NSArray *versionCompatibility = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];

if ( 5 == [[versionCompatibility objectAtIndex:0] intValue] ) { /// iOS5 is installed

    // Put iOS-5 code here

} else { /// iOS4 is installed

    // Put iOS-4 code here         

}

【讨论】:

  • 你也可以使用NSNumericSearch比较选项;)stackoverflow.com/a/1990854/429521
  • 这很棒,因为与当前接受的答案不同,我需要知道用户正在操作哪个 iOs 版本,因为某些 unicode 字符在 iOS6 之前的功能不同(例如 /u200b 在 periOS6 上的长度为 0 但postiOS6 上的长度为 1)
  • 还应该注意的是,如果他们推出更新的 iOs 版本(即 iOS6),您应该这样说if (5 <= ...),您的应用仍将支持您的功能!
  • 是的,非常正确。我是去年匆忙写的。我现在要调整它。
  • 实际上,我将把它作为练习留给读者。也许他们想要 iOS 6 中的特定内容,而 iOS 5 中没有,所以无论如何他们都必须对其进行修改。感谢您的建议和客气话。
【解决方案2】:

在许多情况下,您不需要直接检查 iOS 版本,而是可以检查运行时是否存在特定方法。

在您的情况下,您可以执行以下操作:

if ([[UIView class] respondsToSelector:@selector(animateWithDuration:animations:)]){
// animate using blocks
}
else {
// animate the "old way"
}

【讨论】:

  • [[UIView class] respondsToSelector:@selector(animateWithDuration:animations:)]可以写成[UIView respondsToSelector:@selector(animateWithDuration:animations:)]
  • 我讨厌笼统的陈述。在某些用例中,您必须检查 iOS 版本。我现在正面临这样的用例!!!
  • @JohnConnor,你是对的,在某些情况下你可能需要检查 iOS 版本,但一般来说,如果可能的话,你应该避免这种情况。只是好奇,你是什么情况?
  • @JustinKredible,我也是。就我而言,如果我的应用程序的定位服务被禁用/拒绝,我想主动将它们引导到设置应用程序......除了 iOS 5 和 iOS 6 之间的选项不同。我还能如何为用户提供正确的方向而不是通过知道他们是否在 iOS 6 上?
【解决方案3】:

符合系统定义中指定的版本

//#define __IPHONE_2_0 20000
//#define __IPHONE_2_1 20100
//#define __IPHONE_2_2 20200
//#define __IPHONE_3_0 30000
//#define __IPHONE_3_1 30100
//#define __IPHONE_3_2 30200
//#define __IPHONE_4_0 40000
你可以这样写函数 (您可能应该将此版本存储在某个地方,而不是每次都计算它):

+ (NSInteger) getSystemVersionAsAnInteger{
    int index = 0;
    NSInteger version = 0;

    NSArray* digits = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
    NSEnumerator* enumer = [digits objectEnumerator];
    NSString* number;
    while (number = [enumer nextObject]) {
        if (index>2) {
            break;
        }
        NSInteger multipler = powf(100, 2-index);
        version += [number intValue]*multipler;
        index++;
    }
return version;
}

那么你可以这样使用:

if([Toolbox getSystemVersionAsAnInteger] >= __IPHONE_4_0)
{
  //blocks
} else 
{
  //oldstyle
}

【讨论】:

    【解决方案4】:

    Xcode 7 添加了available 语法,使这相对更简单:

    斯威夫特:

    if #available(iOS 9, *) {
        // iOS 9 only code
    } 
    else {
       // Fallback on earlier versions
    }
    

    Xcode 9 也在 Objective-C 中添加了这种语法

    目标-C:

    if (@available(iOS 9.0, *)) {
       // iOS 9 only code
    } else {
       // Fallback on earlier versions
    }
    

    【讨论】:

    • 是否也可以以类似的方式排除整个 Objective-C 方法或类?
    【解决方案5】:

    这里的大多数解决方案都太过分了。您需要做的就是[[UIDevice currentDevice].systemVersion intValue]。这会自动删除小数点,因此无需拆分字符串。

    所以你可以像这样检查它:

    if ([[UIDevice currentDevice].systemVersion intValue] >= 8) {
        // iOS 8.0 and above
    } else {
        // Anything less than iOS 8.0
    }
    

    您也可以使用以下代码定义宏:

    #define IOS_VERSION [[UIDevice currentDevice].systemVersion intValue];
    

    甚至包括您的支票:

    #define IOS_8PLUS ([[UIDevice currentDevice].systemVersion intValue] >= 8)
    

    那么你只需要这样做:

    if (IOS_8PLUS) {
        // iOS 8.0 and above
    } else {
        // Anything less than iOS 8.0
    }
    

    【讨论】:

      【解决方案6】:

      不鼓励与弃用不同。

      如果您需要支持没有基于块的方法的早期版本的 iOS,使用较旧的方法没有任何问题(当然,只要它们没有被删除)。

      【讨论】:

      • 老实说,如果您不需要基于块的方法的功能,我认为旧方法没有任何问题。
      • 建议将此作为评论或添加有用信息以使其成为答案。不确定为什么它被投票...
      【解决方案7】:

      您可以使用Foundation框架的版本来确定当前的系统版本。

      if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1){
      
      //for earlier versions
      
      } else {
      
      //for iOS 7
      
      }
      

      【讨论】:

        【解决方案8】:

        出于我的目的,我编写了一个小型库,用于抽象出底层 C 调用并提供一个 Objective-C 接口。

        GBDeviceDetails deviceDetails = [GBDeviceInfo deviceDetails];
        if (deviceDetails.iOSVersion >= 6) {
            NSLog(@"It's running at least iOS 6");      //It's running at least iOS 6
        }
        

        除了获取当前iOS版本外,还检测底层设备的硬件,获取屏幕大小信息;都在运行时。

        它在 github 上:GBDeviceInfo。在 Apache 2 下获得许可。

        【讨论】:

          【解决方案9】:

          把它放在你的 Prefix.pch 文件中

          #define IOS_VERSION [[[[[UIDevice currentDevice] systemVersion] componentsSeparatedByString:@"."] firstObject] intValue]
          

          然后您可以检查 iOS 版本,例如:

          if(IOS_VERSION == 8)
          {
               // Hello 8!
          }
          else
          {
               // Hello some other version!
          }
          

          当然,如果您可以使用特征检测(并且这对您的用例有意义),您应该这样做。

          【讨论】:

            【解决方案10】:

            在 MonoTouch 中:

            要获得主要版本,请使用:

            UIDevice.CurrentDevice.SystemVersion.Split('.')[0]
            

            对于次要版本使用:

            UIDevice.CurrentDevice.SystemVersion.Split('.')[1]
            

            【讨论】:

              【解决方案11】:

              对上述解决方案进行更好更高效的适配:

              -(CGPoint)getOsVersion
              {
                  static CGPoint rc = {-1,-1};
                  if (rc.x == -1) {
                      NSArray *versionCompatibility = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
                      rc.x = [versionCompatibility[0] intValue];
                      rc.y = [versionCompatibility[1] intValue];
                  }
                  return rc;
              }
              

              现在可以

              if ([self getOsVersion].x < 7) {
              }
              

              HTH

              【讨论】:

              • 啊,旧的 CGPoint 方法是吗?
              猜你喜欢
              • 1970-01-01
              • 2015-06-26
              • 2010-10-17
              • 2018-07-02
              • 1970-01-01
              • 2019-05-13
              • 2011-09-30
              • 2015-03-19
              相关资源
              最近更新 更多