2010-03-14 10 views
5

¿Existe una forma general de mejores prácticas de notificación cuando se está descartando el controlador de vista actual (ya sea que aparezca o descarte la marca de Dialog ado)? No puedo usar -viewWillDisappear :, ya que también se llama cuando otro viewController se empuja encima del actual.Método llamado al despedir a un UIViewController?

+8

Nota que el IOS 5 proporciona el método '-isBeingDismissed', que puede ser llamado dentro de' viewWillDisappear: '' o viewDidDisappear: ' . Pero eso no ayuda si tiene que admitir versiones anteriores de iOS. –

+0

@ La respuesta de KristopherJohnson debería marcarse como la respuesta correcta hoy en día, ya que iOS 4 es casi inexistente. –

Respuesta

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. Interesante uso de KVO. – kennytm

+0

inteligente, me gusta! –

+0

Tenga en cuenta que esto puede no funcionar como espera si el controlador se "descarta" como resultado de la destitución de uno de sus padres. En este caso, parentViewController no se desactivará, pero el cuadro de diálogo seguirá sin ser visible. Realmente, "despedido" debería estar mejor definido. –

0

Por lo que yo sé, no hay forma automática de recibir notificaciones, pero dado que UIViewController tiene una propiedad modalViewController, podría definir un tipo como "didDismiss ..." y llamar a ese método en el controlador anterior de vista modal después de presentar su nuevo controlador de vista modal.

+0

Claro, pero eso no hace nada para los controladores estándar, no modales, y es frágil (requiere que el padre lo llame). Sé que hay formas de evitar esto, solo tengo curiosidad si hay una "mejor manera de hacerlo" aceptada. –

0

¿Puede aclarar su pregunta?

estoy pensando que usted está pidiendo:

ViewcontrollerONE aparece ViewControllerTWO de forma modal. ViewControllerTWO se descarta. ViewControllerONE quiere saber que That ViewControllerTWO acaba de ignorar a sí mismo, y quiere ejecutar el método XYZ debido a ello.

que no tienen una buena respuesta, pero tengo una manera:

VC1 simplemente se hace referencia en VC2. para que VC2 pueda notificar a VC1 antes de la salida.

+1

No, ViewControllerTWO quiere saber que se descartó la TI. –

0

La respuesta seleccionada con MVA no funcionó para mí en iOS 8.

I subclases UIViewController de la siguiente manera y luego simplemente llame dismissAnimated:completion: en el controlador de vista presentado en lugar de dismissViewControllerAnimated:completion:. Me registro para observar la notificación en otro lugar y desencadenar el manejo según sea necesario.

#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

Apple cambió la forma de presentación está trabajando en iOS8, que están utilizando presentationControllers, porque no son presentationControllers MVA compilant, tuve que usar porque es containerViewremovedFromSuperview y nilled cuando -[UIPresentationController transitionDidFinish:] se llama. Solución para iOS8 y superiores:

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

Estoy añadiendo observador es completionHandler ya que la presentación puede fallar a veces, especialmente cuando se presenta en la presentación ya viewController.

En valor observador i tiene que quitar la observación cuando containerView ya no existe:

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") 
    } 
} 
Cuestiones relacionadas