我想符合 iOS 8 中使用的 UIAlertController,因为 UIAlertView 现在已弃用。有没有一种方法可以在不破坏对 iOS 7 的支持的情况下使用它?是否有某种 if 条件可以检查 iOS 8,否则为 iOS 7 支持做其他事情?
11 回答
我认为检查一个类是否存在(自 iOS 4.2 起)的更好方法是:
if([ClassToBeChecked class]) {
// use it
} else {
// use alternative
}
在你的情况下,那将是:
if ([UIAlertController class]) {
// use UIAlertController
} else {
// use UIAlertView
}
目标C(如上所述)
if ([UIAlertController class]) {
// use UIAlertController
} else {
// use UIAlertView
}
迅速
if objc_getClass("UIAlertController") == nil {
// use UIAlertView
} else {
// use UIAlertController
}
不要使用if NSClassFromString("UIAlertController") == nil
它不起作用,因为此方法的签名是func NSClassFromString(_ aClassName: String!) -> AnyClass!
请参阅Erwan的答案(在我的答案下方),因为我认为它是最好的。
--
您可以检查 iOS 版本以使用适当的控件,如下所示:
if (([[[UIDevice currentDevice] systemVersion] compare:@"8.0" options:NSNumericSearch] == NSOrderedAscending)) {
// use UIAlertView
}
else {
// use UIAlertController
}
正如其他人已经提到的 - 始终检查是否存在功能。我认为最安全的方法如下:
if (NSClassFromString(@"UIAlertController")) {
// use UIAlertController
} else {
// use UIAlertView
}
输入带有拼写错误的类名存在明显的风险。:)
从NClassFromString的文档:
[返回] 由 aClassName 命名的类对象,如果当前没有加载该名称的类,则返回 nil。如果 aClassName 为 nil,则返回 nil。
可用性 iOS(2.0 及更高版本)
在 Swift 中检查 iOS 版本的解决方案
switch (UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch)) {
case .OrderedAscending:
println("iOS < 8.0")
case .OrderedSame, .OrderedDescending:
println("iOS >= 8.0")
}
此解决方案的缺点:无论您采用哪种方式,检查操作系统版本号都是一种不好的做法。永远不要以这种方式对依赖项进行硬编码,始终检查特性、功能或类的存在。考虑一下;Apple 可能会发布类的向后兼容版本,如果他们这样做了,那么您建议的代码将永远不会使用它,因为您的逻辑会查找操作系统版本号而不是类的存在。
(本信息来源)
在 Swift 中检查类是否存在的解决方案
if (objc_getClass("UIAlertController") == nil) {
// iOS 7
} else {
// iOS 8+
}
不要使用if (NSClassFromString("UIAlertController") == nil)
,因为它在使用 iOS 7.1 和 8.2 的 iOS 模拟器上可以正常工作,但是如果你在使用 iOS 7.1 的真实设备上进行测试,你会很遗憾地注意到你永远不会通过代码片段的 else 部分。
// Above ios 8.0
float os_version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (os_version >= 8.000000)
{
//Use UIAlertController
}
else
{
//UIAlertView
}
创建简单utility function
以减少代码
代码 :
// pass minimum required iOS version
BOOL isOSSupported(NSString *minRequiredVersion)
{
NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
BOOL isOSSupported = ([currSysVer compare:minRequiredVersion options:NSNumericSearch] != NSOrderedAscending) &&
![currSysVer isEqualToString:@"Unknown"];
return isOSSupported;
}
利用 :
if(isOSSupported("8.0")
{
// Code for iOS8 and above
}
else
{
// Code for iOS7 and below
}
或使用系统常数
NSFoundationVersionNumber_iOS_7_1
如下
if(floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1)
{
// Code for iOS8 and above
}
else
{
// Code for iOS7 and below
}
更多选项链接
我在 Objective-C 中创建了非常简单的包装器,它同时支持旧的 iOS UIAlertView 和新的UIAlertViewController
https://github.com/MartinPerry/UIAlert/
它还将新的动作块使用带到旧的UIAlertView
样本:
MyAlertMessage * a = [[MyAlertMessage alloc] initWithTitle:@"Hello" WithMessage:@"World"];
[a addButton:BUTTON_OK WithTitle:@"OK" WithAction:^(void *action) {
NSLog(@"Button OK at index 0 click");
}];
[a addButton:BUTTON_CANCEL WithTitle:@"Cancel" WithAction:^(void *action) {
NSLog(@"Button Cancel at index 1 click");
}];
[a show];
我编写了一个类来包装 UIAlertView 并使用 UIAlertController。因为程序员是透明的,因此在项目中导入这些类就足够了。此类的实用性在于,在旧项目中有更多 UIAlertView 需要更改。链接:https ://github.com/kennymuse/UIAlertView
方法一
通过ios系统版本检查
#define iOSVersionLessThan(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
// below ios8 ,create UIAlertView
if(iOSVersionLessThan(@"7.0")){
// todo
// ios8 and above ,UIActionController avaliable
}else{
// todo
}
方法二
通过系统特征检测
// create UIActionController
if([UIActionController class]){
// todo
// create UIAlertView
}else{
// todo
}
但是,还有第三个名为PSTAlertController的库,用于处理向后兼容 iOS 7 的 UIActionSheet 和 UIAlertView。
参考
试试下面的代码。它适用于 iOS 8 及以下版本。
if (IS_OS_8_OR_LATER) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
}];
[alertVC addAction:cancelAction];
[[[[[UIApplication sharedApplication] windows] objectAtIndex:0] rootViewController] presentViewController:alertVC animated:YES completion:^{
}];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
[alert show];
}