2010-12-04 12 views
9

La ventana principal de mi aplicación contiene un UITabBarController basado en xib (completamente configurado en Interface Builder) que también se puede presentar de forma modal (al igual que la vista modal de Music.app "Agregar canciones a la lista de reproducción") . El UITabBarController contiene varios UINavigationControllers que a su vez contienen UITableViewControllers subclassed. Esta es la forma en que estoy detectando actualmente si el UITableViewController subclase se presenta dentro de un UITabBarController modal:Determinar si un UIViewController se presenta de manera modal

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    self.isModal = NO; 

    UIViewController *child  = self; 
    UIViewController *parent = self.parentViewController; 
    while (parent) { 
     if (parent.modalViewController && parent.modalViewController == child) { 
      self.isModal = YES; 
      break; 
     } 
     child = parent; 
     parent = parent.parentViewController; 
    } 

    if (self.isModal) { 
     // modal additions, eg. Done button, navigationItem.prompt 
    } 
    else { 
     // normal additions, eg. Now Playing button 
    } 
} 

¿Hay una manera de hacer esto que no implica subir el árbol parentViewController o subclasificación de toda la visión intermedia Controladores para pasar el estado isModal cuando se inicializan?

Respuesta

4

Got an answer on Twitter. Terminé subclasificando UITabBarController y agregando una propiedad de instancia BOOL isModal que se establece en SÍ cuando se presenta modalmente. A continuación, las subvistas pueden usar self.tabBarController con un molde a la subclase para acceder a la propiedad isModal y renderizar/comportarse en consecuencia.

+3

Fundición a la subclase. Eso parece incomodo. ¿Por qué subclase? ¿Por qué no agregar una categoría a UITabBarController que contiene isModal? –

1

Puede establecer el estado de visualización en un inicializador personalizado cuando presente la vista. Quiero decir que el código que lo presenta sabrá cómo se presenta, ¿verdad?

- (void)initInModalMode:(BOOL)isModal 

es mejor que tener la vista retroactivamente descubrir su estado más adelante?

+0

Se sabe que está presentando un UITabBarController pero no sabe que está presentando el UITableViewController subclase (que es presentado por uno de los muchos UINavigationControllers intermedios presentado por el UITabBarController) que realmente necesita saber si se está presentando modalmente o no. ¿Este enfoque no me obligaría a clasificar por subclase todos los controladores de vista intermedia de otro modo para garantizar que el valor de isModal llegue a la vista necesaria? –

2

Me gustaría obtener el controlador de vista raíz y comprobar si tiene un controlador de vista modal. Puede obtener ese controlador de vista desde UIWindow. Tenga en cuenta también que puede iterar a través de la jerarquía del controlador de vista actual utilizando la propiedad viewControllers de UINavigationController: para (UIViewController * viewController en self.navigationController.viewControllers) {...} es más rápido y más simple.

+0

No entiendo cómo cualquiera de las sugerencias se conecta a mi pregunta (no dice que no, simplemente no entiendo). Si un botón en UIWindow> UITabBarController> UINavigationBarController> ACustomTableViewController presenta la misma jerarquía UITabBarController de forma modal, ¿cómo sabe el controlador raíz UITabBarController en UIWindow qué está sucediendo? Respecto a self.navigationController.viewControllers, ¿no contiene solo la jerarquía dentro del navigationController actual? ¿Cómo me ayuda eso en la vista modal que presenta una instancia separada del mismo UITabBarController? –

+0

Cuando está cargando su UITabBarController, si es el controlador raízView de la ventana UI actual, no coloca el botón Hecho en la interfaz de usuario. De lo contrario, va a estar por encima de ese rootViewController (probablemente modal, pero debe verificar para estar seguro). Está pensando en términos de la jerarquía de vista actual ... – chockenberry

+0

El otro comentario sobre iterar a través de los controladores de vista fue solo para mostrarle que no necesitó verificar a los padres, etc. No ayuda con el problema de saber si usted es modal o no. – chockenberry

10

Si una búsqueda de iOS 6 +, esta respuesta es obsoleto y debe comprobar Gabriele Petronella's answer


respondí una pregunta muy similar hace un tiempo, en el que tengo una función para determinar si el regulador de corriente se presenta como modal o no, sin la necesidad de subclase el controlador de la barra de pestañas aquí:

Is it possible to determine whether ViewController is presented as Modal?

al Answ originales er hay algunas explicaciones básicas sobre cómo funciona esta función y se cancheck allí si es necesario, pero aquí se

-(BOOL)isModal { 

    BOOL isModal = ((self.parentViewController && self.parentViewController.modalViewController == self) || 
      //or if I have a navigation controller, check if its parent modal view controller is self navigation controller 
      (self.navigationController && self.navigationController.parentViewController && self.navigationController.parentViewController.modalViewController == self.navigationController) || 
      //or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation 
      [[[self tabBarController] parentViewController] isKindOfClass:[UITabBarController class]]); 

    //iOS 5+ 
    if (!isModal && [self respondsToSelector:@selector(presentingViewController)]) { 

     isModal = ((self.presentingViewController && self.presentingViewController.modalViewController == self) || 
      //or if I have a navigation controller, check if its parent modal view controller is self navigation controller 
      (self.navigationController && self.navigationController.presentingViewController && self.navigationController.presentingViewController.modalViewController == self.navigationController) || 
      //or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation 
      [[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]]); 

    } 

    return isModal;   

} 
4

Desde IOS5 también se puede utilizar isBeingPresented en una instancia viewController:

- (BOOL)isModalViewController 
{ 
    return [self isBeingPresented]; 
} 
0

Hay una manera mucho más fácil en estos días Swift.

extension UIViewController { 

    var isPresentedModally: Bool { 
     return presentingViewController?.presentedViewController == self || parent?.isPresentedModally == true 
    } 

} 
Cuestiones relacionadas