Mientras investigaba una fuga de memoria, descubrí un problema relacionado con la técnica de llamar setRootViewController:
dentro de un bloque de animación de transición:
[UIView transitionWithView:self.window
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromLeft
animations:^{ self.window.rootViewController = newController; }
completion:nil];
Si el controlador de vista anterior (el que se está reemplazando) presenta actualmente otro controlador de vista, entonces el código anterior no elimina la vista presentada de la jerarquía de vistas.
Es decir, esta secuencia de operaciones ...
- X se convierte en controlador de vista raíz
- X presenta Y, por lo que la vista de Y está en pantalla
- Usando
transitionWithView:
para hacer de Z el nuevo controlador de vista raíz
... se ve bien para el usuario, pero la herramienta Jerarquía de vista de depuración revelará que la vista de Y todavía está detrás de la vista de Z, dentro de a UITransitionView
. Es decir, después de los tres pasos anteriores, la jerarquía de vistas es:
- UIWindow
- UITransitionView
- UIView (vista de Y)
- UIView (vista de Z)
- UITransitionView
Sospecho que esto es un problema porque, en el momento de la transición, la vista de X no es realmente parte de la jerarquía de vista.
Si envío dismissViewControllerAnimated:NO
a X inmediatamente antes transitionWithView:
, la jerarquía de vista resultante es:
- UIWindow
- UIView (vista de X)
- UIView (vista de Z)
Si envío dismissViewControllerAnimated:
(SÍ o NO) a X, luego realizo la transición en el completion:
bloque, entonces la jerarquía de vista es correcta. Desafortunadamente, eso interfiere con la animación. Si anima el despido, pierde tiempo; si no está animando, parece roto.
Estoy intentando algunos otros enfoques (por ejemplo, crear una nueva clase de controlador de vista de contenedor para que sirva como mi controlador de vista raíz) pero no he encontrado nada que funcione. Actualizaré esta pregunta sobre la marcha.
El objetivo final es hacer la transición de la vista presentada a un nuevo controlador de vista raíz directamente y sin dejar jerarquías de vista perdidas.
UIWindow
es cambiarlo, pero no he tenido tiempo de experimentar mucho.Respuestas:
Recientemente tuve un problema similar. Tuve que eliminarlo manualmente
UITransitionView
de la ventana para solucionar el problema, luego llamar a descartar en el controlador de vista raíz anterior para asegurarme de que se desasigne.La solución no es muy buena, pero a menos que haya encontrado una mejor manera desde que publiqué la pregunta, ¡es lo único que he encontrado que funciona!
viewController
es solo elnewController
de tu pregunta original.Espero que esto también te ayude a solucionar tu problema, ¡es un verdadero dolor de cabeza!
(Ver historial de edición para otras versiones de Swift)
Para una implementación más agradable como una extensión para
UIWindow
permitir que se pase una transición opcional.Uso:
O
fuente
UITransitionView
en su aplicación como parte de los símbolos de la aplicación que creo que la App Store usa para verificar.Enfrenté este problema y me molestó durante todo un día. Probé la solución obj-c de @ Rich y resulta que cuando quiera presentar otro viewController después de eso, seré bloqueado con un UITransitionView en blanco.
Finalmente, lo descubrí de esta manera y funcionó para mí.
Muy bien, ahora todo lo que tienes que hacer es llamar
[self setRootViewController:newViewController];
cuando quieras cambiar el controlador de vista raíz.fuente
dismissViewControllerAnimated:
miradas quizás sea un poco mejor que no tener animación. SinUITransitionView
embargo, evita los fantasmas en la jerarquía de vistas.Intento algo simple que funciona para mí en iOs 9.3: simplemente elimine la vista anterior de viewController de su jerarquía durante la
dismissViewControllerAnimated
finalización.Trabajemos en la vista X, Y y Z como explica benzado :
Que dan:
En mi caso, X e Y están bien repartidos y su punto de vista ya no está en jerarquía.
fuente
Tuve un problema similar. En mi caso, tenía una jerarquía de viewController, y uno de los controladores de vista secundarios tenía un controlador de vista presentado. Cuando cambié el controlador de vista raíz de Windows, por alguna razón, el controlador de vista presentado todavía estaba en la memoria. Entonces, la solución fue descartar todos los controladores de vista antes de cambiar el controlador de vista raíz de Windows.
fuente
Llegué a este problema al usar este código:
Al deshabilitar este código, se solucionó el problema. Logré que esto funcionara habilitando solo esta animación de transición cuando se inicializa la barra de filtros que se anima.
No es realmente la respuesta que está buscando, pero podría llevarlo a la plataforma adecuada para encontrar la solución.
fuente