UIAlertController in ausgelagerter Methode aufrufen

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • UIAlertController in ausgelagerter Methode aufrufen

    ich fürchte, ich habe mich irgendwie verirrt ?( :rolleyes: <X
    ich habe einen ViewController. Für die Inhalte muss ich Informationen zusammen tragen und aufarbeiten. Das wurde mit der Zeit so viel an Code, dass ich das besser ausgelagert habe. Sonst hätte ich weit über 1000 Zeilen in meinem UiViewController

    ich habe also in einer Klasse match.m eine Methode readMatch erstellt die mir die Informationen in einem Dictionary liefert.
    self.boardDict = [match readMatch:matchLink];

    funktioniert soweit alles super :thumbup:

    Jetzt komme ich aber zu einem Punkt, an dem ich bei der Datenanalyse auf Fehler stossen kann, die ich gerne anzeigen würde.
    Im Prinzip ist das auch alles klar, funktioniert auch schon an anderer Stelle in meinen Projekten.

    nur eben in der ausgelagerten Methode nicht.
    Ich mache das so:

    C-Quellcode

    1. UIAlertController * alert = [UIAlertController
    2. alertControllerWithTitle:@"caption"
    3. message:[element content]
    4. preferredStyle:UIAlertControllerStyleAlert];
    5. UIAlertAction* yesButton = [UIAlertAction
    6. actionWithTitle:@"OK"
    7. style:UIAlertActionStyleDefault
    8. handler:^(UIAlertAction * action)
    9. {
    10. }];
    11. [alert addAction:yesButton];
    12. [self presentViewController:alert animated:YES completion:nil];
    Alles anzeigen
    Auch im Debugger läuft das einfach durch den Code durch ohne den UIAlertController anzuzeigen.


    ich vermute mal , dass das Problem hier liegt:

    C-Quellcode

    1. [self presentViewController:alert animated:YES completion:nil];
    geht das überhaupt so, wie ich das machen will?


    Wie würde man das richtig machen ?
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


    Hape42
  • Das Problem ist, dass self der View Controller sein muss, in dem der Alert angezeigt werden soll. Eine Lösung wäre, deine ausgelagerte Methode den UIAlertController zurückgeben zu lassen.

    Quellcode

    1. [self presentViewController:[Helper getAlertController] animated:YES completion:nil];
  • Vyax schrieb:

    Das Problem ist, dass self der View Controller sein muss, in dem der Alert angezeigt werden soll. Eine Lösung wäre, deine ausgelagerte Methode den UIAlertController zurückgeben zu lassen.

    Quellcode

    1. [self presentViewController:[Helper getAlertController] animated:YES completion:nil];
    daran hatte ich auch schon gedacht, das wäre auch recht einfach umzusetzen.

    Nur gebe ich dann an einer Stelle zurück, an der ich noch gar nicht aus der Methode austeigen will.

    Kann ich „irgendwie“ den viewController an die Methode „übergeben“ und dann „self“ dadurch ersetzen? <X
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


    Hape42
  • hape42 schrieb:

    Nur gebe ich dann an einer Stelle zurück, an der ich noch gar nicht aus der Methode austeigen will.

    Dir ist aber schon klar, dass die Anzeige des UIAlertController quasi asynchron funktioniert? D.h. nach dem Aufruf von presentViewController:animated:completion: wird direkt der nachfolgende Code ausgeführt.

    Mir ist daher nicht ganz klar, wie Du bei Anzeige des UIAlertController weiterhin "in der" Methode bleiben willst.
  • MyMattes schrieb:

    Inzwischen nutze ich eine Methode im AppDelegate, die einen Alarm über allen Views einblendet.
    Okay, hier kommt‘s:

    Quellcode

    1. - (void)showAlertWithError:(NSError *)error
    2. {
    3. // The displaying controller is created with an additional window, so no controller needs to be passed to this method
    4. NSString *defaultTitle = NSLocalizedStringWithDefaultValue (@"errorAlertTitle", nil, [NSBundle mainBundle], @"strErrorAlertTitle", @"Title of error alert");
    5. NSString *title = ([error localizedFailureReason]) ? [error localizedFailureReason] : defaultTitle;
    6. NSString *message = [error localizedRecoverySuggestion] ? [error localizedRecoverySuggestion] : [error localizedDescription];
    7. __block UIWindow* topWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    8. topWindow.rootViewController = [UIViewController new];
    9. NSString *button = NSLocalizedStringWithDefaultValue (@"errorAlertOK", nil, [NSBundle mainBundle], @"strErrorAlertOK", @"Title of error alert button");
    10. UIAlertController *myAlert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    11. UIAlertAction *okAction = [UIAlertAction actionWithTitle:button style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
    12. {
    13. [myAlert dismissViewControllerAnimated:YES completion:nil];
    14. topWindow = nil;
    15. [self.window makeKeyAndVisible];
    16. }];
    17. [myAlert addAction:okAction];
    18. topWindow.windowLevel = UIWindowLevelAlert + 1;
    19. [topWindow makeKeyAndVisible];
    20. [topWindow.rootViewController presentViewController:myAlert animated:YES completion:nil];
    21. DebugLog(@"Alert \"%@\" (%@)", title, message);
    22. }
    Alles anzeigen
    Die Methode liegt im AppDelegate, bekommt ein NSError-Objekt übergeben und erzeugt ein eigenes Windows: Daher ist die Übergabe eines ViewControllers unnötig.

    Ich fand‘s die (bisher) beste Lösung (der Input kam von SO).

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • MCDan schrieb:

    hape42 schrieb:

    Nur gebe ich dann an einer Stelle zurück, an der ich noch gar nicht aus der Methode austeigen will.
    Dir ist aber schon klar, dass die Anzeige des UIAlertController quasi asynchron funktioniert? D.h. nach dem Aufruf von presentViewController:animated:completion: wird direkt der nachfolgende Code ausgeführt.

    Mir ist daher nicht ganz klar, wie Du bei Anzeige des UIAlertController weiterhin "in der" Methode bleiben willst.
    öhm, nö. Eigentlich logisch. Da hätte sicher gestutzt bei der Umsetzung :D
    Danke für den Hinweis :thumbsup:

    Ich könnte dann zwar im Completion Handler weiter machen, aber das ist irgendwie auch nicht richtig.

    ich denke, das beste ist nochmal zurück an das Reißbrett :rolleyes:
    Ich habe auch keine Loesung, aber ich bewundere das Problem!
    _____________________________________________________


    Hape42
  • MyMattes schrieb:

    MyMattes schrieb:

    Inzwischen nutze ich eine Methode im AppDelegate, die einen Alarm über allen Views einblendet.
    Okay, hier kommt‘s:

    Quellcode

    1. - (void)showAlertWithError:(NSError *)error
    2. {
    3. // The displaying controller is created with an additional window, so no controller needs to be passed to this method
    4. NSString *defaultTitle = NSLocalizedStringWithDefaultValue (@"errorAlertTitle", nil, [NSBundle mainBundle], @"strErrorAlertTitle", @"Title of error alert");
    5. NSString *title = ([error localizedFailureReason]) ? [error localizedFailureReason] : defaultTitle;
    6. NSString *message = [error localizedRecoverySuggestion] ? [error localizedRecoverySuggestion] : [error localizedDescription];
    7. __block UIWindow* topWindow = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    8. topWindow.rootViewController = [UIViewController new];
    9. NSString *button = NSLocalizedStringWithDefaultValue (@"errorAlertOK", nil, [NSBundle mainBundle], @"strErrorAlertOK", @"Title of error alert button");
    10. UIAlertController *myAlert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    11. UIAlertAction *okAction = [UIAlertAction actionWithTitle:button style:UIAlertActionStyleDefault handler:^(UIAlertAction * action)
    12. {
    13. [myAlert dismissViewControllerAnimated:YES completion:nil];
    14. topWindow = nil;
    15. [self.window makeKeyAndVisible];
    16. }];
    17. [myAlert addAction:okAction];
    18. topWindow.windowLevel = UIWindowLevelAlert + 1;
    19. [topWindow makeKeyAndVisible];
    20. [topWindow.rootViewController presentViewController:myAlert animated:YES completion:nil];
    21. DebugLog(@"Alert \"%@\" (%@)", title, message);
    22. }
    Alles anzeigen
    Die Methode liegt im AppDelegate, bekommt ein NSError-Objekt übergeben und erzeugt ein eigenes Windows: Daher ist die Übergabe eines ViewControllers unnötig.

    Ich fand‘s die (bisher) beste Lösung (der Input kam von SO).

    Mattes
    In einer ähnlichen Art und Weise war das auch eine Empfehlung von "Apple".

    stackoverflow.com/a/30941356