2

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?

dopcn
  • 4,218
  • 3
  • 23
  • 32

1 Answers1

0

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];
Community
  • 1
  • 1
John Farkerson
  • 2,543
  • 2
  • 23
  • 33
  • I have already called the AlertView in Class B from Class A. And I have presented the alert in Class A (Class B returned the AlertViewController). Now, is it possible to catch the "ok AlertButton" action from Class A? Should I declare a delegate in B? or A? This I wanna figure out. – Mauricio Pimienta Sosa Aug 09 '16 at 15:32