我目前正在检查 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
operatingSystemVersion
或isOperatingSystemAtLeastVersion
。这将产生以下结果:
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 中将图像居中