Present “Controller” from another Class in Objecti

2019-07-18 11:48发布

问题:

How does one present a UIAlertController from another class?

I want to know how can you capture the action of an "ok" button in a UIAlertController that was created in Class B but presented in Class A.

This is how I call the method that created the Alert on class "ErrorHandler" from ClassA:

ErrorHandler *handler = [[ErrorHandler alloc] init];
[self presentViewController:[handler alertWithInternetErrorCode] animated:YES completion:nil];

And this is the implementation of alertWithInternetErrorCode in the ErrorHandler.m:

- (UIAlertController *)alertWithInternetErrorCode{

    UIAlertController * alert = [UIAlertController
                                 alertControllerWithTitle:@"Error"
                                 message:@"No internet conneciton"
                                 preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction * cancel = [UIAlertAction
                              actionWithTitle:@"Cancel"
                              style:UIAlertActionStyleCancel
                              handler:^(UIAlertAction * action) {
                                  NSLog(@"cancelled");
                              }];

    [alert addAction:cancel];
    return alert;
}

Again, I want to know how to be able to create these kind of objects in other classes and still be able to present them in the class where you call them. That includes capturing their actions. In this case it would be the NSLog action inside the "cancel button". Would it be possible to call even a method instead of the NSLog? Let's say a delegate method and navigate back to the code in Class A?

回答1:

2 choices:

The Best Option:

Pass the controller into the method like so: - (UIAlertController *)alertWithInternetErrorCodeInPresenter: (UIViewController *) presenter

Call [presenter presentViewController: alert animated:YES completion:nil];

If this isn't possible:

UIViewController *rootVC = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[rootVC presentViewController:alert animated:YES completion:nil];

Edit – to capture actions:

- (void) presentAlertWithInternetErrorCodeInPresenter:(UIViewController<CustomAlertViewProtocol> *) presenter{

    UIAlertController * alert = [UIAlertController
                             alertControllerWithTitle:@"Error"
                             message:@"No internet connection"
                             preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction * cancel = [UIAlertAction
                          actionWithTitle:@"Cancel"
                          style:UIAlertActionStyleCancel
                          handler:^(UIAlertAction * action) {
                              [presenter cancelPressed];//Here's the key
                          }];

    [alert addAction:cancel];
    [presenter presentViewController: alert animated:YES completion:nil];
}

In the ErrorHandler.h file you must declare this protocol:

@protocol CustomAlertViewProtocol
- (void) cancelPressed;
@end

Now in any view controller .h file where you want to use this method, you must tell the compiler that you are following the CustomAlertViewProtocol:

@interface MyViewController : UIViewController <CustomAlertViewProtocol>

And in the .m you must implement the protocol method:

- (void) cancelPressed {
    //Do whatever you want
}

Now to actually show an alert:

ErrorHandler *handler = [[ErrorHandler alloc] init];//Or whatever initializer you use
[handler presentAlertWithInternetErrorCodeInPresenter: self];