我目前正在检查 UIAlertController 是不是存在以确定正在使用的操作系统版本。有没有更有效的方法来做到这一点?

Posted

技术标签:

【中文标题】我目前正在检查 UIAlertController 是不是存在以确定正在使用的操作系统版本。有没有更有效的方法来做到这一点?【英文标题】:I'm currently checking if UIAlertController exists to determine what OS version is being used. Is there a more efficient way to do this?我目前正在检查 UIAlertController 是否存在以确定正在使用的操作系统版本。有没有更有效的方法来做到这一点? 【发布时间】:2014-10-13 13:33:59 【问题描述】:

我在一个单元格上有一个删除按钮,它在 ios7 中使我的应用程序崩溃,但在 iOS8 中却没有。后来我发现崩溃是由于我对视图层次结构的深入挖掘造成的。

为了让事情更清楚,这里是解决问题的代码:

func didTapDeleteButton(sender: UIButton) 
        var cell: HoursOfOperationTableViewCell!
        if let gotModernAlert: AnyClass = NSClassFromString("UIAlertController") 
            println("UIAlertController can be instantiated")
            //make and use a UIAlertController
            cell = sender.superview?.superview? as HoursOfOperationTableViewCell
        
        else        
            println("UIAlertController can NOT be instantiated")
            cell = sender.superview?.superview?.superview? as HoursOfOperationTableViewCell
        

如您所见,我必须深入到视图层次结构中才能访问 iOS 7 中的自定义单元格视图。

我想知道是否有更有效的方法来检查 iOS 版本?

如果我不检查,如果我留下这样的代码,我的应用程序会在 iOS7 中崩溃:

cell = sender.superview?.superview? as HoursOfOperationTableViewCell

感谢您的宝贵时间。

【问题讨论】:

你做对了。最好检查类的存在,而不是操作系统版本。也许类名会改变,也许它会在 iOS 12 中被弃用/删除,等等。 我认为没有合适的解决方案?你能解释一下为什么吗? @DanielGalasko 我已经搁置了我项目的这一部分,但很快就会回来尝试这些解决方案。 【参考方案1】:

要测试一个类是否在当前运行时加载,您可以调用以下代码:

var classExistsAndIsSafeToUse = countElements(NSStringFromClass(object_getClass(UIAlertController))) > 0

您应该始终检查是否存在特定类而不是检查 iOS 版本。

话虽如此,为了检查 iOS 版本,下面是我在 just that 上的解决方案的摘录

iOS 8 中的新功能是NSProcessInfo,它与 Swift 和 允许更好的语义版本检查。感谢NSHipster 我们可以看到一个干净和规范的来源,操作系统版本可以从其中 推导出来。

iOS 8.0 或更高版本的最低部署目标,请使用NSProcessInfo operatingSystemVersionisOperatingSystemAtLeastVersion

这将产生以下结果:

let minimumVersion = NSOperatingSystemVersion(majorVersion: 3, minorVersion: 1, patchVersion: 3)
if NSProcessInfo().isOperatingSystemAtLeastVersion(minimumVersion) 
    //do some fun stuff

对于 iOS 7.1 或更低版本的最低部署目标,请使用 compare with NSStringCompareOptions.NumericSearch UIDevice systemVersion

这将产生:

let minimumVersionString = "3.1.3"
let versionComparison: NSComparisonResult = UIDevice.currentDevice().systemVersion.compare(minimumVersionString,

选项:NSStringCompareOptions.NumericSearch) 如果 versionComparison == .OrderedDescending //做一些有趣的事情

编辑

作为旁注,如果您看到这样的内容:

cell = sender.superview?.superview? as HoursOfOperationTableViewCell

你的代码已经开始表现出所谓的代码异味,你应该考虑在你的视图中实现你的视图逻辑,控制器不应该对视图层次结构有深入的了解。请记住,目标是编写易于更改的代码。考虑实施抽象、委托和单一职责原则设计。

祝你好运

【讨论】:

【参考方案2】:

您可以简单地查看[[UIDevice currentDevice] systemVersion]。这将返回一个NSString,因此如果您想比较,则需要转换为浮点数。

【讨论】:

【参考方案3】:

另一种方法是使用NSFoundationVersionNumber。在保存全局常量的文件中声明以下常量。

let iOS7 = floor(NSFoundationVersionNumber) <= floor(NSFoundationVersionNumber_iOS_7_1)
let iOS8 = floor(NSFoundationVersionNumber) > floor(NSFoundationVersionNumber_iOS_7_1)

然后像这样检查版本。

if iOS8 
    // Use iOS 8 APIs
 else 
    // Fallback for older iOS versions

【讨论】:

以上是关于我目前正在检查 UIAlertController 是不是存在以确定正在使用的操作系统版本。有没有更有效的方法来做到这一点?的主要内容,如果未能解决你的问题,请参考以下文章

检查UIAlertController是否已经呈现的最佳方法是什么?

CocoaAction / 带有 UIAlertController 的操作

如何在 UIAlertController 中向 UITextField 添加边距?

在 UIAlertController 中的 UIAlertAction 中将图像居中

检查 UIAlertController TextField 以启用按钮

iOS 7 和 iOS 8 中的警报视图与 UIAlertController