2009-09-08 1 views
6

Ich habe eine Ansicht mit einer Schaltfläche zurück mit einem Navigationscontroller verwaltet und ich möchte überprüfen, ob eine Datei gespeichert wurde, wenn der Benutzer auf die Schaltfläche Zurück klicken. Wenn die Datei gespeichert wurde, kehren Sie in der vorherigen Ansicht zurück, sonst fragt Sie eine Benutzeransicht, ob Sie die Datei speichern möchten oder nicht.iphone navigationController: warten auf uialertview Antwort vor dem Beenden der aktuellen Ansicht

Also habe ich das gemacht, aber die Ansicht verschwindet und der Alertview erscheint danach.

-(void)viewWillDisappear:(BOOL)animated { 
if(!self.fileSaved){ 
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Save the file?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil]; 
    [alert show]; 
    [alert release]; 
} 
} 

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex 
{ 
switch (buttonIndex) { 
    case 0: 
     NSLog(@"NO"); 
     break; 
    case 1: 
     NSLog(@"yes"); 
     break; 
    default: 
     break; 
} 
} 

Antwort

6

Wenn viewWillDisappear aufgerufen wird, ist es bereits zu spät. Sie sollten den Zurück-Knopf früher abfangen. Ich habe es nie getan, aber mein Vorschlag ist, die Delegierten auf der navigationbar Eigenschaft in Ihrem viewDidAppear Verfahren einzustellen:

// save the previous delegate (create an ivar for that) 
prevNavigationBarDelegate = self.navigationController.navigationBar.delegate; 

self.navigationController.navigationBar.delegate = self; 

Vergessen Sie nicht, es in viewWillDisappear zurück zu setzen:

self.navigationController.navigationBar.delegate = prevNavigationBarDelegate; 

Dann abfangen die shouldPopItem Methode:

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { 
    if(!self.fileSaved) { 
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Save the file?" delegate:self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil]; 
     [alert show]; 
     [alert release]; 

     return NO; 
    } 

    if ([prevNavigationBarDelegate respondsToSelector:@selector(navigationBar:shouldPopItem:)]) 
     return [prevNavigationBarDelegate navigationBar:navigationBar shouldPopItem:item]; 

    return YES; 
} 

Und in den JA-Handler für den Dialog, pop manuell den Controller:

0.123.
[self.navigationController popViewController:YES]; 
+0

Klingt logisch, aber Sie sollten wahrscheinlich sparen Die aktuelle Navigationsleiste Delegieren Sie vor dem Überschreiben, setzen Sie es zurück, nachdem Sie sich entschieden haben, sich selbst zu popularisieren und vielleicht sogar den 'navigationBar: shallPopItem: 'Aufruf an den alten Delegaten (wenn nicht NULL) vor dem Anzeigen Ihrer Warnung. – pix0r

+0

Die Alertview erscheint nicht mit diesem Code – Mathieu

+0

@Mathieu: Wird die Methode shouldPopItem aufgerufen? Wenn nicht, müssen Sie möglicherweise den Delegaten in der viewDidAppear-Methode anstelle der init-Methode festlegen. Der Kommentar von pix0r ist ebenfalls gültig. Ich werde meine Antwort aktualisieren, um das zu reflektieren. –

4

Sie müssen UINavigationController von der Klasse ableiten, damit dies funktioniert. Dann überschreiben - (BOOL) navigationBar: (UINavigationBar *) navigationBar shouldPopItem: (UINavigationItem *) item. Sie sollten ein benutzerdefiniertes Delegate-Protokoll einrichten, das von den View-Controllern übernommen wird. Wenn Sie zulassen, dass Popup aufgerufen wird, rufen Sie Ihre [super navigationBar sollPopItem:] auf. Andernfalls geben Sie NO zur obigen Methode zurück.

+0

Ich habe dies implementiert und kann überprüfen, dass es funktioniert und meiner Meinung nach ist der sauberste Weg, dies zu erreichen. –

2

Wäre es nicht einfacher, nur einen linken Knopf Element wie im folgenden hinzuzufügen:

UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveThisDate)]; 
self.navigationItem.leftBarButtonItem = backButton; 
[backButton release]; 
+0

Ich probierte all die anderen komplizierten Sachen aus anderen Posts aus, aber diese funktionierte wie ein Zauber ohne die Komplikationen. – gangt

+0

Gleichermaßen. Wenn Sie einen Navigationscontroller im Spiel haben und möchten, dass Ihre Aktion nur für einen bestimmten Viewcontroller ausgeführt wird, glaube ich, dass dies der einzige Weg ist. – Chris

0

Um auf nobre Reaktion zu verfolgen und wie Jon es erwähnt, ist der beste Weg UINavigationController Unterklasse.

Der einfachste Weg und schnellster Weg, dies acheive:

  1. die Klasse Ihrer Navigationssteuerung im Interface Builder Ändern von CustomNavigationControllerDelegate erben

Custom navigation class

  1. Implementieren Sie das CustomNavigationControllerDelegate-Protokoll in Ihrem UIViewController

@interface YourViewController <CustomNavigationControllerDelegate>

#pragma mark - UINavigationBar Delegate Methods 
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { 

    UIAlertView* alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:self cancelButtonTitle:cancel otherButtonTitles:ok, nil]; 
    alert.tag = kpopup_back; 
    [alert show]; 

    return NO; 
} 
  1. dem Controller als Delegierter registrieren

#pragma mark - viewWillAppear - (void) viewWillAppear:(BOOL)animated { ((CustomNavigationController*)self.navigationController).customDelegate = self; }

  1. Schließlich und wichtig Teil, ENTFERNEN Sie den Delegaten (um zu vermeiden, dass Sie sich beim Pop erneut auslösen), und setzen Sie den Controller selbst in das UIAlertViewDelegate

case kpopup_back : { if(buttonIndex != 0) //OK { ((CustomNavigationController*)self.navigationController).customDelegate = nil; [self.navigationController popViewControllerAnimated:YES]; } } break;

Es funktioniert einwandfrei auf meiner Seite, hoffe, es kann helfen.


Hier sind die Quellen:

CustomNavigationControllerDelegate.h

#import <UIKit/UIKit.h> 

@protocol CustomNavigationControllerDelegate <NSObject> 
@optional 
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item; 
@end 

@interface CustomNavigationController : UINavigationController 

@property (nonatomic, retain) id<CustomNavigationControllerDelegate> customDelegate; 

@end 

CustomNavigationControllerDelegate.m

#import "CustomNavigationController.h" 

@interface CustomNavigationController() 

@end 

@implementation CustomNavigationController 

- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item { 

    if (_customDelegate && [_customDelegate respondsToSelector:@selector(navigationBar:shouldPopItem:)]) { 
     return [_customDelegate navigationBar:navigationBar shouldPopItem:item]; 
    } 

    return YES; 
} 

@end 
Verwandte Themen