Show UIAlertController from a common utility class

两盒软妹~` 提交于 2019-12-11 06:06:57

问题


I am working on a project that uses UIAlertView, now the problem is I have to replace all of the UIAlertView's with UIAlertController's and there are around 1250 of them in the code. I am planning to uses the existing Utility class to create a function that does this, following is what I am planning to do:

+(void)showAlert:(NSString *)title errorMessage:(NSString *)msg {
    UIAlertController *alertController = [UIAlertController 
    alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
    [self presentViewController:alertController animated:YES completion:nil];
}

I have the following questions before doing this: 1 - Is this worth the efforts (Using UIAlertController instead of UIAlertView) ? 2 - How do I handle UIAlertView's that had tags and different delegate implementation across hundreds of files ? 3 - The fourth line the function above gives an error : No known class method for selector 'presentViewController:animated:completion:'

Any help is greatly appreciated.


回答1:


You've to use UIAlertController as UIAlertView is deprecated.

Apple Doc says:

In apps that run in versions of iOS prior to iOS 8, use the UIAlertView class to display an alert message to the user. An alert view functions similar to but differs in appearance from an action sheet (an instance of UIActionSheet). UIAlertView is deprecated in iOS 8. (Note that UIAlertViewDelegate is also deprecated.) To create and manage alerts in iOS 8 and later, instead use UIAlertController with a preferredStyle of UIAlertControllerStyleAlert. Availability

Alternatively, you can do this way. In your Utils Class, do this:

+ (void)showAlertWithTitle:(NSString *)title message:(NSString *)msg controller:(id)controller {
    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];

    [alertController addAction:okAction];

    [controller presentViewController:alertController animated:YES completion:nil];
}

Usage from your ViewController class:

[Utils showAlertWithTitle:@"Camera" message:@"It seems that your device doesn't support camera. " controller: self];

If your existing UIAlertView is having tags then you've to use the UIAlertViewController class instead of the Util method.

Hope it helps.




回答2:


You can use a common alertcontroller class method. Here is an example how you can solve the no.4 error. Basically you pass also the viewController that wants to call the alertview.

+(UIImage *)showAlert:(NSString *)title errorMessage:(NSString *)msg inViewController:(id)vc {
    UIAlertController *alertController = [UIAlertController 
    alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
    [alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
    [vc presentViewController:alertController animated:YES completion:nil];
}

On the issue of alertviews with tags that require user input, to handle those inputs you might want to put the handler in and not let it nil and turn your method into a completionBlock method:

+(UIImage *)showAlert:(NSString *)title message:(NSString *)msg inViewController:(id)vc completedWithBtnStr:(void(^)(NSString* btnString))completedWithBtnStr {
    UIAlertController *alertController = [UIAlertController 
    alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];

    [alertController addAction:[UIAlertAction actionWithTitle:@"Yes" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
      completedWithBtnStr(@"Yes");
    }]];
    [alertController addAction:[UIAlertAction actionWithTitle:@"No" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
      completedWithBtnStr(@"No");
    }]];
    [vc presentViewController:alertController animated:YES completion:nil];
}

An example of calling this is

[YourClass showAlert:@"Sure?" message:@"Delete this record?" inViewController:self completedWithBtnStr:^(NSString* btnString) {
  if ([btnString isEqualToString:@"Yes"]) {
    // delete record
  }
}];

The parameter btnString can be anything really. The code is not tested so if you found error, do inform me.




回答3:


Answering your questions:

  1. It's definitely worth doing that. You have to use UIAlertController anyway in near future as of UIAlertview is deprecated.
  2. Use blocks or protocol to get a callback when delegate methods in utility class are fired.
  3. Looks like you are presenting that on NSObject. Present on view class. In this case, you can use window rootViewController to present on



回答4:


+(void) showAlert
{
    UIWindow* topWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    topWindow.rootViewController = [UIViewController new];
    topWindow.windowLevel = UIWindowLevelAlert + 1;

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"title" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction* okButton = [UIAlertAction
                               actionWithTitle:@"OK"
                               style:UIAlertActionStyleDefault
                               handler:^(UIAlertAction * action) {
                                   //Handle your yes please button action here
                                   topWindow.hidden = YES;
//your ok button action handling
                               }];
    [alertController addAction:okButton];

    [topWindow makeKeyAndVisible];
    [topWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
}


来源:https://stackoverflow.com/questions/43778603/show-uialertcontroller-from-a-common-utility-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!