UIAlertView/UIAlertController兼容iOS 7和iOS 8

Sha*_*han 57 uialertview ios swift uialertcontroller

我正在使用Swift编写应用程序,我需要显示警报.该应用必须兼容iOS 7和iOS 8.由于UIAlertView已被替换UIAlertController,如何在UIAlertController不检查系统版本的情况下检查是否可用?我听说Apple建议我们不要检查设备的系统版本,以确定API的可用性.

这就是我在iOS 8中使用的,但是在iOS 7上用" dyld: Symbol not found: _OBJC_CLASS_$_UIAlertAction" 崩溃了:

let alert = UIAlertController(title: "Error", message: message, preferredStyle: .Alert)
let cancelAction = UIAlertAction(title: "OK", style: .Cancel, handler: nil)
alert.addAction(cancelAction)
presentViewController(alert, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)

如果我使用UIAlertView for iOS 8,我收到此警告: Warning: Attempt to dismiss from view controller <_UIAlertShimPresentingViewController: 0x7bf72d60> while a presentation or dismiss is in progress!

War*_*ton 76

检测模式与Objective-C风格相同.

您需要检测当前活动运行时是否能够实例化此类

if objc_getClass("UIAlertController") != nil {

     println("UIAlertController can be instantiated")

      //make and use a UIAlertController

 }
 else {

      println("UIAlertController can NOT be instantiated")

      //make and use a UIAlertView
}
Run Code Online (Sandbox Code Playgroud)

不要尝试根据操作系统版本来解决这个问题.你需要检测不是 OS的能力.

编辑

此答案的原始检测器NSClassFromString("UIAlertController")-O优化下失败,因此它已更改为适用于发布版本的当前版本

编辑2

NSClassFromString 正在Xcode 6.3/Swift 1.2中进行所有优化

  • 谢谢.这回答了我原来的问题,因为我已经读过其他帖子,你不应该检查操作系统版本来检测能力. (2认同)

Sam*_*m B 29

对于非swift代码,纯Objective-C执行此操作

if ([UIAlertController class])
    {
        // use UIAlertController
        UIAlertController *alert= [UIAlertController
                                      alertControllerWithTitle:@"Enter Folder Name"
                                      message:@"Keep it short and sweet"
                                      preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault
                                                   handler:^(UIAlertAction * action){
                                                       //Do Some action here
                                                       UITextField *textField = alert.textFields[0];
                                                       NSLog(@"text was %@", textField.text);

                                                   }];
        UIAlertAction* cancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault
                                                       handler:^(UIAlertAction * action) {

                                                           NSLog(@"cancel btn");

                                                           [alert dismissViewControllerAnimated:YES completion:nil];

                                                       }];

        [alert addAction:ok];
        [alert addAction:cancel];

        [alert addTextFieldWithConfigurationHandler:^(UITextField *textField) {
            textField.placeholder = @"folder name";
            textField.keyboardType = UIKeyboardTypeDefault;
        }];

        [self presentViewController:alert animated:YES completion:nil];

    }
    else
    {
        // use UIAlertView
        UIAlertView* dialog = [[UIAlertView alloc] initWithTitle:@"Enter Folder Name"
                                                         message:@"Keep it short and sweet"
                                                        delegate:self
                                               cancelButtonTitle:@"Cancel"
                                               otherButtonTitles:@"OK", nil];

        dialog.alertViewStyle = UIAlertViewStylePlainTextInput;
        dialog.tag = 400;
        [dialog show];

    }
Run Code Online (Sandbox Code Playgroud)


Bay*_*ips 9

我很生气,我不得不写出两种情况,所以我写了一个兼容的UIAlertController,适用于iOS 7,所以我把它扔在GitHub上.我尽力复制(更好)添加UIAlertController的按钮和动作的方法.适用于Objective-C和Swift.我正在发布这个,因为我在Google上搜索时发现了这个问题,并认为它对其他人有帮助.

https://github.com/BayPhillips/compatible-alert-controller


Shi*_*aay 8

您可以使用以下代码解决问题: -

var device : UIDevice = UIDevice.currentDevice()!;
        var systemVersion = device.systemVersion;
        var iosVerion : Float = systemVersion.bridgeToObjectiveC().floatValue;
        if(iosVerion < 8.0) {
            let alert = UIAlertView()
            alert.title = "Noop"
            alert.message = "Nothing to verify"
            alert.addButtonWithTitle("Click")
            alert.show()
        }else{
            var alert : UIAlertController = UIAlertController(title: "Noop", message: "Nothing to verify", preferredStyle: UIAlertControllerStyle.Alert)
            alert.addAction(UIAlertAction(title: "Click", style:.Default, handler: nil))
            self.presentViewController(alert, animated: true, completion: nil)
        }
Run Code Online (Sandbox Code Playgroud)

和UIKit必须标记为Optional而不是Required.

Courtsey: - 可以在iOS 7和iOS 8上运行的警报

  • 检查特定的iOS版本被认为是不好的做法 - 最好检查一个类是"已知"还是"响应选择器". (4认同)

Wil*_* Hu 6

Swift 2.0

 if #available(iOS 8.0, *) {

 } else {

 }
Run Code Online (Sandbox Code Playgroud)