2010-03-14 7 views
5

Gibt es einen allgemeinen Best-Practice-Weg, um benachrichtigt zu werden, wenn der aktuelle View-Controller abgewiesen wird (entweder popped oder disfidModalDialog)? Ich kann -viewWillDisappear: nicht verwenden, da dies auch aufgerufen wird, wenn ein anderer viewController über den aktuellen ViewController geschoben wird.Methode beim Ablehnen eines UIViewController aufgerufen?

+8

Beachten Sie, dass iOS 5 stellt das Verfahren '-isBeingDismissed', die innerhalb' viewWillDisappear genannt werden kann: 'oder' viewDidDisappear: ' . Aber das hilft nicht, wenn Sie frühere Versionen von iOS unterstützen müssen. –

+0

@ KristopherJohnson Antwort sollte jetzt als die richtige Antwort markiert werden, dass iOS 4 ist so gut wie nicht vorhanden. –

Antwort

11
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) { 
     [self addObserver:self forKeyPath:@"parentViewController" options:0 context:NULL]; 
    } 
    return self; 
} 


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if ([@"parentViewController" isEqualToString:keyPath] && object == self) { 
     if (!self.parentViewController) 
      NSLog(@"Dismissed"); 
    } 
} 

- (void)dealloc 
{ 
    [self removeObserver:self forKeyPath:@"parentViewController"]; 
    [super dealloc]; 
} 
+0

+1. Interessanter Einsatz von KVO. – kennytm

+0

clever, ich mag es! –

+0

Denken Sie daran, dass dies möglicherweise nicht so funktioniert, wie Sie es erwarten, wenn der Controller als Folge der Entlassung eines Elternteils "entlassen" wird. In diesem Fall wird parentViewController nicht deaktiviert, aber das Dialogfeld wird nicht mehr angezeigt. Wirklich, "entlassen" sollte besser definiert werden. –

0

Soweit ich weiß, gibt es keine automatische Möglichkeit, benachrichtigt zu werden, aber da UIViewController eine modalViewController-Eigenschaft besitzt, könnten Sie ein ähnliches "didDiss ..." definieren und diese Methode auf dem vorherigen Modal-View-Controller aufrufen neuer Modal View Controller.

+0

Sicher, aber das macht nichts für standardmäßige, nicht-modale Controller, und es ist zerbrechlich (es erfordert die Eltern, es zu nennen). Ich weiß, dass es Möglichkeiten gibt, ich bin nur neugierig, ob es dort einen akzeptierten "besten Weg" gibt. –

0

Können Sie Ihre Frage klären?

Ich denke, dass Sie fragen:

ViewcontrollerONE ViewControllerTWO erscheint modal. ViewControllerTWO wird geschlossen. ViewControllerONE möchte wissen, dass That ViewControllerTWO gerade sich selbst abgetan hat und deswegen XYZ-Methode ausführen möchte.

Ich habe keine gute Antwort, aber ich habe eine Art und Weise haben:

VC1 einfach in VC2 verwiesen wird. VC2 kann daher VC1 vor der Kündigung benachrichtigen.

+1

Nein, ViewControllerTWO möchte wissen, dass IT abgelehnt wurde. –

0

Die gewählte Antwort mit KVO nicht auf iOS für mich arbeiten 8.

I subclassed UIViewController wie folgt und dann auf Ich nenne nur dismissAnimated:completion: der dargebotenen View-Controller statt dismissViewControllerAnimated:completion:. Ich melde mich an, um die Benachrichtigung an anderer Stelle zu beobachten und die Behandlung nach Bedarf auszulösen.

#define DismissNotifyViewControllerDismissedNotification @"DismissNotifyViewControllerDismissed" 


@interface DismissNotifyViewController : UIViewController 

- (void)dismissAnimated:(BOOL)flag completion:(void (^)(void))completion; 

@end 


@implementation DismissNotifyViewController 

- (void)dismissAnimated:(BOOL)flag completion:(void (^)(void))completion 
{ 
    [self.presentingViewController dismissViewControllerAnimated: flag 
                 completion: ^{ 

      if (completion) 
       completion(); 

      [NSNotificationCenter.defaultCenter 
        postNotificationName: DismissNotifyViewControllerDismissedNotification 
        object: self]; 
    }]; 
} 

@end 
0

Apfel verändert, wie Präsentation in iOS8 arbeitet, sie presentationControllers verwenden, weil presentationControllers nicht KVO compilant, ich hatte containerView zu verwenden, weil es removedFromSuperview und nilled ist, wenn -[UIPresentationController transitionDidFinish:] genannt wird. Lösung für iOS8 und oben:

self.presentationContext.presentViewController(self.viewControllerToPresent, animated: true, completion: { _ in 
    self.viewControllerToPresent.presentationController?.addObserver(self, forKeyPath: "containerView", options: [], context: &self.observingContext) 
}) 

I Beobachter ist Zugabe ist completionHandler weil Präsentation manchmal besonders fehlschlagen kann, wenn bereits präsentiert auf der Präsentation Viewcontroller.

In Beobachter Wert Ich habe Beobachtung zu entfernen, wenn containerView nicht mehr existiert:

override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 
    guard &self.observingContext == context else { 
     super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context) 
     return 
    } 
    if let presentationController = object as? UIPresentationController where presentationController.containerView == nil { 
     presentationController.removeObserver(self, forKeyPath: "containerView") 
    } 
} 
Verwandte Themen