He leído muchos mensajes acerca de la gente que tiene problemas con viewWillAppear cuando no de crear la vista de jerarquía sólo derecho. Mi problema es que no puedo averiguar lo que significa.

Si puedo crear un RootViewController y llame a addSubView en ese controlador, yo esperaría que el agregado de la vista(s) para estar conectado para viewWillAppear eventos.

¿Alguien tiene un ejemplo de un complejo programático de la vista de jerarquía que recibe correctamente viewWillAppear eventos en cada nivel?

De Apple Docs estado:

Advertencia: Si el punto de vista de la pertenencia a un controlador de vista se agrega a una jerarquía directamente, el controlador de vista de no recibir este mensaje. Si usted insertar o añadir una vista a la vista de jerarquía, y tiene una vista controlador, debe de enviar a los asociados de controlador de vista de este mensaje directamente. Error al enviar el controlador de vista de este mensaje, se evitará cualquier asociado de la animación que se muestra.

El problema es que ellos no describen cómo hacerlo. ¿Qué significa «directamente» significa? ¿Cómo que «indirectamente» añadir un punto de vista?

Soy bastante nuevo en el Cacao y el iPhone, así que sería bueno si hubo ejemplos útiles de Apple además de la básica Hola Mundo de mierda.

  • He tenido este problema hasta que me di cuenta de que yo estaba mal de la comprensión de la intención de uso de UIViewController subclases en general. Echa un vistazo a esta Pregunta. stackoverflow.com/questions/5691226/…
  • Por favor, ten cuidado!!! Ya No es cierto en iOS 5 !!! Llamadas viewWillAppear y viewDidAppear automáticamente
InformationsquelleAutor chzk | 2008-09-25

25 Comentarios

  1. 54

    Si utiliza un controlador de navegación y establecer su delegado, la vista{Le,Hizo}{Aparecen,Desaparecen} métodos no son invocados.

    Que usted necesita para utilizar la navegación controlador de los métodos de delegado lugar:

    navigationController:willShowViewController:animated:
    navigationController:didShowViewController:animated:
    • No me había fijado mi navegación del controlador de delegado y todavía el método no estaba llamado. De todos modos, lo puse y luego he utilizado los métodos que mencionas arriba. Gracias.
    • Estoy viendo la misma cosa como Dimitris
    • Acabo de probar esto en iOS4 y iOS5: Esto NO es cierto: Ajuste el delegado de un navigationController y, a continuación, empujando una vista a fuego viewWillAppear: etc.
    • Swift 3: func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animados: Bool) {} Y func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animados: Bool) {}
    • No funciona!
  2. 29

    Me he encontrado con este mismo problema. Sólo tienes que enviar un viewWillAppear mensaje a su controlador de vista antes de añadir una subvista. (Hay un parámetro BOOL que indica al controlador de vista si es que se animan a aparecer o no).

    [myViewController viewWillAppear:NO];

    Mirar RootViewController.m en el Metrónomo ejemplo.

    (De hecho, encontré Apple ejemplo, en proyectos grandes. Hay MUCHO más que HelloWorld 😉

    • En realidad, usted debe llamar a viewWillAppear después de agregarlo a la subvista. De lo contrario, IBOutlets/IBActions no estar conectado.
    • Sí, después. Creado subvista de XIB, viewWillAppear no lo llamaban. Llamada por mí mismo, y todo funciona bien.
    • Gracias! Esto fue exactamente lo que para mí. Yo estaba añadir manualmente una subvista a través de [scrollView addSubview:controller.view];. He añadido la línea [controller viewWillAppear:NO]; después y ¡voilá! Trabajó como un encanto.
    • En toda la probabilidad, esto es debido a que su UIViewController es el control de un punto de vista que es una subvista de una vista controlado por otro UIViewController. Esta no es la intención de patrón de diseño. Para más información echa un vistazo a este post. stackoverflow.com/questions/5691226/…
    • Por favor, ten cuidado!!! Ya No es cierto en iOS 5 !!! Llamadas viewWillAppear y viewDidAppear automáticamente. Si usted llama de forma manual, sería llamado dos veces.
    • Con vista anidada, todavía tengo que llamar a este manual, incluso para iOS7. A continuación, funciona de maravilla.
    • Cómo si el niño / a controlador de vista se agrega desde el storyboard?
    • nunca han estado en lo correcto – a veces llamada viewWillAppear: del sistema y llama al mismo método. viewWillAppear: en su propia clase siempre llama [super viewWillAppear:animated];. Llamar dos veces puede haber resultado impredecible. Y, por supuesto, – ¿por qué has elegido un delegado existente método en lugar de su propio?

  3. 18

    Finalmente encontré una solución para esto QUE FUNCIONA!

    UINavigationControllerDelegate

    Creo que el quid de la cuestión es establecer el nav de control del delegado para el viewcontroller es en e implementar UINavigationControllerDelegate y se trata de dos métodos. Genial! Estoy tan emocionado de que finalmente he encontrado una solución!

    • cómo asignar un rootviewcontroller como delegado para navigationcontroller?
    • NO funciona! trate de minimizar la aplicación y maximizar
  4. 8

    Yo sólo tenía el mismo problema. En mi aplicación tengo 2 controladores de navegación y pulsar el mismo controlador de vista en cada uno de ellos trabajó en un caso y no en el otro. Me refiero a que cuando se empuja el mismo controlador de vista en la primera UINavigationController, viewWillAppear fue llamado, pero no cuando empujó en el segundo controlador de navegación.

    Luego me encontré con este post UINavigationController debe llamar viewWillAppear/viewWillDisappear métodos

    Y se dio cuenta de que mi segunda navegación controlador hizo redefinir viewWillAppear. La detección del código mostró que no estaba llamando a

    [super viewWillAppear:animated];

    He añadido y trabajado !

    La documentación dice:

    Si reemplazar este método, usted debe llamar a super en algún momento de su aplicación.

    • Lo mismo aquí. Jodido por no llamar a super.
  5. 5

    He estado usando un controlador de navegación. Cuando quiero descender a otro nivel de datos o mostrar mi vista personalizada utilizo las siguientes:

    [self.navigationController pushViewController:<view> animated:<BOOL>];

    Cuando hago esto, hago la viewWillAppear función a fuego. Supongo que esto califica como «indirecta» porque yo no estoy llamando a la real addSubView método de mí mismo. No sé si esto es 100% aplicable a su aplicación, ya que no puede saber si usted está utilizando un controlador de navegación, pero tal vez va a proporcionar una pista.

  6. 4

    En primer lugar, la barra de pestañas debe ser a nivel de la raíz, es decir, agrega a la ventana, como se indica en la documentación de Apple. Esta es la clave para el comportamiento correcto.

    En segundo lugar, usted puede uso UITabBarDelegate /UINavigationBarDelegate para reenviar las notificaciones en forma manual, pero me pareció que para obtener toda la jerarquía de ver las llamadas para que funcione correctamente, todo lo que tenía que hacer era llamar manualmente

    [tabBarController viewWillAppear:NO];
    [tabBarController viewDidAppear:NO];

    y

    [navBarController viewWillAppear:NO];
    [navBarController viewDidAppear:NO];

    .. solo una VEZ antes de configurar el punto de vista de los controladores en el respectivo controlador (a la derecha después de la asignación). A partir de entonces, correctamente llamado a estos métodos en su hijo la vista de los controladores.

    La jerarquía es como este:

    window
        UITabBarController (subclass of)
            UIViewController (subclass of) //<-- manually calls [navController viewWill/DidAppear
                UINavigationController (subclass of)
                    UIViewController (subclass of) //<-- still receives viewWill/Did..etc all the way down from a tab switch at the top of the chain without needing to use ANY delegate methods

    Con sólo llamar a los métodos mencionados en la ficha/nav controlador de la primera vez que se aseguró de que TODOS los acontecimientos que se han enviado correctamente. Se me paró la necesidad de llamar de forma manual desde el UINavigationBarDelegate /UITabBarControllerDelegate métodos.

    Nota al margen:
    Curiosamente, cuando no trabajo, el método privado

    - (void)transitionFromViewController:(UIViewController*)aFromViewController toViewController:(UIViewController*)aToViewController 

    .. que se puede ver en la pila de llamadas en un trabajo de implementación, por lo general llama la viewWill/Did.. métodos, pero no lo hice hasta que me realizó el anterior (aunque se llamaba).

    Creo que es MUY importante que el UITabBarController es a nivel de ventana y aunque los documentos parecen respaldar esto.

    Esperanza de que fue clara(ish), encantados de responder a más preguntas.

  7. 3

    Como la respuesta no es aceptado y la gente (como yo) de la tierra aquí doy mi variación. Aunque no estoy seguro de que ese era el problema original. Cuando el controlador de navegación se agrega como una subvista a un otro punto de vista se debe llamar a la viewWillAppear/a Desaparecer etc. los métodos de la siguiente manera:

    - (void) viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
    
        [subNavCntlr viewWillAppear:animated];
    }
    
    - (void) viewWillDisappear:(BOOL)animated
    {
        [super viewWillDisappear:animated];
    
        [subNavCntlr viewWillDisappear:animated];
    }

    Sólo para hacer el ejemplo completo. Este código aparece en mi ViewController donde he creado y añadido a la navegación controlador en una vista que me coloca en la vista.

    - (void)viewDidLoad {
    
        //This is the root View Controller
        rootTable *rootTableController = [[rootTable alloc]
                     initWithStyle:UITableViewStyleGrouped];
    
        subNavCntlr = [[UINavigationController alloc]   
                      initWithRootViewController:rootTableController];
    
        [rootTableController release];
    
        subNavCntlr.view.frame = subNavContainer.bounds;
    
        [subNavContainer addSubview:subNavCntlr.view];
    
        [super viewDidLoad];
    }

    el .h se parece a esto

    @interface navTestViewController : UIViewController <UINavigationControllerDelegate> {
        IBOutlet UIView *subNavContainer;
        UINavigationController *subNavCntlr;
    }
    
    @end

    En el archivo nib tengo el vista y por debajo de este punto de vista que tiene una etiqueta de una imagen y el contenedor (otra vista) donde puedo poner el controlador en. Aquí es lo que parece. He tenido que revolver algunas cosas como este fue el trabajo para un cliente.

    iPhone viewWillAppear no disparo

  8. 3

    Vistas son agregó que «directamente» llamando [view addSubview:subview].
    Las vistas son agregó que «indirectamente» a través de métodos tales como la ficha de bares o barras de navegación que swap subvistas.

    Cualquier momento de llamar [view addSubview:subviewController.view], a continuación, usted debe llamar a [subviewController viewWillAppear:NO] (o SÍ, como tu caso).

    He tenido este problema cuando he implementado mi propia raíz personalizadas-ver sistema de gestión para una dynpro en un juego. Adición manual de la llamada a viewWillAppear curar mi problema.

  9. 3

    Forma correcta de hacer esto es utilizando UIViewController de contención de la api.

    - (void)viewDidLoad {
         [super viewDidLoad];
         //Do any additional setup after loading the view.
         UIViewController *viewController = ...;
         [self addChildViewController:viewController];
         [self.view addSubview:viewController.view];
         [viewController didMoveToParentViewController:self];
    }
    • Esta es sin duda la solución moderna (iOS 9,8,7). También, si usted está cambiando, integrado en el controlador de vista sobre la marcha, usted tendrá que llamar a [viewController willMoveToParentViewController:nil]; [viewController.ver removeFromSuperview]; [viewController removeFromParentViewController];
    • En este caso viewWillAppear: todavía no puede ser llamado
  10. 2

    Puedo usar este código para insertar y extraer la vista de los controladores:

    push:

    [self.navigationController pushViewController:detaiViewController animated:YES];
    [detailNewsViewController viewWillAppear:YES];

    pop:

    [[self.navigationController popViewControllerAnimated:YES] viewWillAppear:YES];

    .. y funciona muy bien para mí.

  11. 2

    Un error muy común es como sigue.
    Usted tiene una opinión, UIView* a, y otra, UIView* b.
    Añadir b a a como una subvista.
    Si intenta llamar a viewWillAppear en la b, nunca va a ser despedido, porque es una subvista de un

  12. 2

    Gracias iOS 13.

    ViewWillDisappear, ViewDidDisappear, ViewWillAppear y
    ViewDidAppear no se llama en la presentación de un controlador de vista en
    iOS 13 que utiliza una nueva modal presentación que no cubre el
    toda la pantalla.

    Créditos van a Arek Holko. Él realmente me salvó el día.

    iPhone viewWillAppear no disparo

  13. 1

    No estoy 100% seguro de esto, pero creo que la adición de una vista a la vista de jerarquía directamente significa llamar a la -addSubview: en la vista del controlador de la vista (por ejemplo, [viewController.view addSubview:anotherViewController.view]) en lugar de empujar un nuevo controlador de vista sobre la navegación del controlador de la pila.

  14. 1

    Creo que la adición de una subvista no significa necesariamente que la vista se parecen, así que no es una llamada automática a la clase del método que se va a

  15. 1

    Yo pienso que lo que significa «directamente» es por el enlace de cosas de la misma manera como el xcode «Aplicación de Navegación» de la plantilla, lo que establece el UINavigationController como el único subvista de la aplicación del UIWindow.

    Con esa plantilla es la única manera en la que he sido capaz de obtener la Se/Hizo/Aparecer/Desaparecer métodos llamados en el objeto ViewControllers en push/pop de los controladores en el UINavigationController. Ninguna de las otras soluciones en las respuestas aquí trabajó para mí, incluyendo la aplicación de ellos en la RootController y que pasa a través de el (hijo) NavigationController. Esas funciones (se/hizo/aparecer/desaparecer) sólo fueron llamados en mi RootController al mostrar/ocultar el nivel superior de la VCs, mi «inicio de sesión» y navigationVCs, no el sub-VCs en el controlador de navegación, por lo que no tuve oportunidad de «pasar a través» de la Nav VC.

    Terminé usando el UINavigationController del delegado de la funcionalidad para buscar el particular transiciones que requiere el seguimiento de la funcionalidad en mi aplicación, y que funciona, pero requiere un poco más de trabajo con el fin de obtener tanto el desaparecer y aparecer la funcionalidad de «simulado».

    También es una cuestión de principio para llegar a trabajar después de golpear mi cabeza contra este problema para horas de hoy. Cualquier trabajo de fragmentos de código utilizando una costumbre RootController y un niño de navegación VC sería muy apreciada.

  16. 1

    En caso de que esto le ayuda a nadie. He tenido un problema similar donde mi ViewWillAppear no está desencadenando en un UITableViewController. Después de un montón de jugar, me di cuenta de que el problema era que el UINavigationController que es el control de mi UITableView no está en la raíz de la vista. Una vez que arreglarlo, ahora está trabajando como un campeón.

    • Puede por favor compartir el «cómo» se hizo eso?
  17. 1

    Yo sólo tenía este problema mí y me tomó 3 horas (de las cuales 2 googlear) para solucionarlo.

    Lo que resultó fue simplemente eliminar la aplicación desde el dispositivo/simulador, limpia y, a continuación, ejecute de nuevo.

    Espero que ayude

  18. 1
    [self.navigationController setDelegate:self];

    Establecer el delegado de la raíz de controlador de vista.

    • Podría agregar «donde» colocar este código?
    • no funciona
  19. 1

    Para Swift. En primer lugar crear el protocolo de llamar a lo que usted quería llamar en viewWillAppear

    protocol MyViewWillAppearProtocol{func myViewWillAppear()}

    Segundo, crear la clase

    class ForceUpdateOnViewAppear: NSObject, UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool){
        if let updatedCntllr: MyViewWillAppearProtocol = viewController as? MyViewWillAppearProtocol{
            updatedCntllr.myViewWillAppear()
        }
    }

    }

    Tercero, hacer que la instancia de ForceUpdateOnViewAppear de ser miembro de la clase que tiene el acceso a la Navegación Controlador y existe mientras la Navegación controlador existe. Puede ser, por ejemplo, la raíz de controlador de vista de la navegación controlador o en la clase que crea o lo presente. A continuación, asigne la instancia de ForceUpdateOnViewAppear a la Navegación Controlador delegado de la propiedad tan pronto como sea posible.

  20. 0

    En mi caso el problema fue con la costumbre de animación de transición.
    Cuando se establece modalPresentationStyle = .custom viewWillAppear no se llama

    en la costumbre de transición de la clase de animación necesidad de llamar a los métodos:
    beginAppearanceTransition y endAppearanceTransition

  21. 0

    En mi caso que era un extraño bug en ios 12.1 emulador. Desapareció después de su lanzamiento el dispositivo real.

  22. 0

    He creado una clase que resuelve este problema.
    Sólo tienes que configurar como delegado de su controlador de navegación, y de implementar simples de una o dos métodos en el controlador de vista – que le llama cuando la vista está a punto de ser mostrado o ha sido demostrado a través de NavigationController

    Aquí está la ESENCIA mostrando el código

  23. 0

    ViewWillAppear es un método de reemplazo de UIViewController clase, de modo que la adición de una subvista no llame viewWillAppear, pero cuando usted presente, push , pop, mostrar , setFront O popToRootViewController de un viewController, a continuación, viewWillAppear por la presentada viewController será llamado.

  24. -2

    No estoy seguro de que este es el mismo problema que he resuelto.

    En algunas ocasiones, el método no ejecutado con forma normal, tales como «[auto methodOne]».

    Intentar

    - (void)viewWillAppear:(BOOL)animated
    {
        [self performSelector:@selector(methodOne) 
               withObject:nil afterDelay:0];
    }
    • el problema es viewWillAppear no está llamado a todos los
  25. -3

    Usted debe de tener sólo 1 UIViewController activo en cualquier momento. Cualquier subvistas desea manipular debería ser exactamente eso – subvistas – es decir, UIView.

    Yo uso un simlple técnica para la gestión de mi punto de vista de la jerarquía y aún tienen que ejecutar en un problema desde que empecé a hacer las cosas de esta manera. Hay 2 puntos clave:

    • una sola UIViewController debe ser utilizado para gestionar «una pantalla vale la pena»
      de su aplicación
    • uso UINavigationController para cambiar de vista

    ¿Qué quiero decir con «una pantalla vale la pena»? Es un poco vaga a propósito, pero en general es una función o sección de la aplicación. Si tienes un par de pantallas con la misma imagen de fondo pero diferentes superposiciones/pop-ups, etc., que debe ser de 1 controlador de vista y varios puntos de vista. Usted nunca debe encontrarte trabajando con 2 vista de los controladores. Nota puede crear una instancia de una UIView en un controlador de vista y añadir un subvista de otro punto de vista controlador si desea que ciertas áreas de la pantalla que se muestra en la vista varios de los controladores.

    Como para UINavigationController – esta es su mejor amigo! Desactivar la barra de navegación y especificar NINGUNA de dibujos animados, y tienes una excelente manera de cambiar de pantalla en la demanda. Usted puede push y pop de vista de los controladores de si están en una jerarquía, o se puede preparar una matriz de vista de los controladores (incluyendo una matriz que contiene un único VC) y ponerlo en la pila de vista de uso de setViewControllers. Esto le da total libertad para cambiar de VC, mientras que el aumento de todas las ventajas de trabajar dentro de Apple que se espera del modelo y obtención de todos los eventos, etc. se activó correctamente.

    Aquí es lo que yo hago cada vez que inicie una aplicación:

    • inicio desde la ventana de una aplicación basada en
    • agregar un UINavigationController como la ventana del rootViewController
    • añadir lo que yo quiero que mi primera UIViewController a ser como el rootViewController de la nav
      controlador de

    (nota a partir de la ventana es sólo una preferencia personal, me gusta construir cosas de mí mismo, así que sé exactamente cómo se construyen. Debería funcionar bien con la función de la vista de la plantilla)

    Todos los eventos de fuego correctamente y, básicamente, la vida es buena. Usted puede gastar todo su tiempo a escribir el importante bits de la aplicación y no meterse tratando de piratear manualmente la vista de las jerarquías en forma.

    • No hay nada de malo con tener múltiples vista de los controladores de activos; UIViewController tiene métodos para permitir una jerarquía para ser construido (por ejemplo, [addChildViewController:]).
    • Sí lo hace ahora. En 2011 no. La respuesta fue precisa en el tiempo, es cierto que no es ahora.

Dejar respuesta

Please enter your comment!
Please enter your name here