UIAlertController if iOS 8, otherwise UIAlertView

后端 未结 11 2006
清酒与你
清酒与你 2020-12-16 10:19

I want to conform to the UIAlertController used in iOS 8 since UIAlertView is now deprecated. Is there a way that I can use this without breaking support for iOS 7? Is there

相关标签:
11条回答
  • 2020-12-16 10:38

    Method one

    by ios system version check

    #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
    }
    

    Method two

    by system feature detect

    // create UIActionController 
    if([UIActionController class]){
        // todo
    // create UIAlertView
    }else{
        // todo
    }
    

    But,there's a third lib named PSTAlertController that deal with backwards compatible to iOS 7 of UIActionSheet and UIAlertView.

    ref to

    • Supporting Multiple Versions of iOS
    • Supporting iOS 6
    • Supporting Multiple iOS Versions and Devices
    0 讨论(0)
  • 2020-12-16 10:40

    Solution for checking iOS version in Swift

    switch (UIDevice.currentDevice().systemVersion.compare("8.0.0", options: NSStringCompareOptions.NumericSearch)) {
        case .OrderedAscending:
           println("iOS < 8.0")
    
        case .OrderedSame, .OrderedDescending:
           println("iOS >= 8.0")
    }
    

    Con of this solution: it is simply bad practice to check against OS version numbers, whichever way you do it. One should never hard code dependencies in this way, always check for features, capabilities or the existence of a class. Consider this; Apple may release a backwards compatible version of a class, if they did then the code you suggest would never use it as your logic looks for an OS version number and NOT the existence of the class.

    (Source of this information)

    Solution for checking the class' existence in Swift

    if (objc_getClass("UIAlertController") == nil) {
       // iOS 7
    } else {
       // iOS 8+
    }
    

    Do not use if (NSClassFromString("UIAlertController") == nil) because it works correctly on the iOS simulator using iOS 7.1 and 8.2, but if you test on a real device using iOS 7.1, you will unfortunately notice that you will never pass through the else part of the code snippet.

    0 讨论(0)
  • 2020-12-16 10:47

    I have created very simple wrapper in Objective-C, that supports both - old iOS UIAlertView and new one UIAlertViewController

    https://github.com/MartinPerry/UIAlert/

    It also brings the new action blocks usage to old UIAlertView

    Sample:

    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];
    
    0 讨论(0)
  • 2020-12-16 10:48

    I think a much better way to check if a class exists (since iOS 4.2) is:

    if([ClassToBeChecked class]) {
    
       // use it
    
    } else {
    
      // use alternative
    
    }
    

    In your case, that would be:

    if ([UIAlertController class]) {
       // use UIAlertController
    
    } else {
      // use UIAlertView
    
    }
    
    0 讨论(0)
  • 2020-12-16 10:49

    Please see the answer of Erwan (below my answer) as I see it is the best.

    --

    You can check the iOS version to use appropriate control like this:

    if (([[[UIDevice currentDevice] systemVersion] compare:@"8.0" options:NSNumericSearch] == NSOrderedAscending)) {
        // use UIAlertView
    }
    else {
        // use UIAlertController
    }
    
    0 讨论(0)
  • 2020-12-16 10:50

    As others have already mentioned - always check whether a feature exists. I believe the safest approach is following:

    if (NSClassFromString(@"UIAlertController")) {
        // use UIAlertController
    } else {
        // use UIAlertView
    }
    

    With the obvious risk of entering a class name with a typo. :)

    From documentation of NClassFromString:

    [Returns] The class object named by aClassName, or nil if no class by that name is currently loaded. If aClassName is nil, returns nil.

    Availability iOS (2.0 and later)

    0 讨论(0)
提交回复
热议问题