Una vista de contenedor se puede agregar fácilmente a un guión gráfico a través del editor de interfaz. Cuando se agrega, una vista de contenedor es una vista de marcador de posición, un segue incrustado y un controlador de vista (secundario).
Sin embargo, no puedo encontrar una manera de agregar una Vista de contenedor mediante programación. En realidad, ni siquiera puedo encontrar una clase con el nombre UIContainerView
o algo así.
Un nombre para la clase de Container View es sin duda un buen comienzo. Se agradecerá mucho una guía completa que incluya el segue.
Conozco la Guía de programación de View Controller, pero no la considero igual a la forma en que Interface Builder lo hace para Container Viewer. Por ejemplo, cuando las restricciones se establecen correctamente, la vista (secundaria) se adaptará a los cambios de tamaño en la Vista de contenedor.
fuente
ViewController
ciclo de vida del incrustado . ElViewController
ciclo de vida del incrustado por Interface Builder es normal, pero el agregado mediante programación no tieneviewDidAppear
niviewWillAppear(_:)
niviewWillDisappear
.viewWillAppear
yviewWillDisappear
en el controlador de vista secundario, está bien. Si tiene un ejemplo donde no lo son, debe aclararlo o publicar su propia pregunta preguntando por qué no lo son.Respuestas:
Una "vista de contenedor" del guión gráfico es solo un
UIView
objeto estándar . No hay un tipo especial de "vista de contenedor". De hecho, si observa la jerarquía de vistas, puede ver que la "vista de contenedor" es un estándarUIView
:Para lograr esto de manera programática, emplea "contención del controlador de vista":
instantiateViewController(withIdentifier:)
al objeto del guión gráfico.addChild
a su controlador de vista de padres.view
a su jerarquía de vista conaddSubview
(y también establezca lasframe
restricciones o según corresponda).didMove(toParent:)
método en el controlador de vista secundario, pasando la referencia al controlador de vista principal.Consulte Implementación de un controlador de vista de contenedor en la Guía de programación del controlador de vista y la sección "Implementación de un controlador de vista de contenedor" de la Referencia de clase de UIViewController .
Por ejemplo, en Swift 4.2 podría verse así:
Tenga en cuenta que lo anterior en realidad no agrega una "vista de contenedor" a la jerarquía. Si quieres hacer eso, harías algo como:
Este último patrón es extremadamente útil si alguna vez se realiza la transición entre diferentes controladores de vista infantil y solo desea asegurarse de que la vista de un niño esté en la misma ubicación y la vista del niño anterior (es decir, todas las restricciones únicas para la ubicación están dictadas por la vista del contenedor, en lugar de tener que reconstruir estas limitaciones cada vez). Pero si solo realiza una contención de vista simple, la necesidad de esta vista de contenedor separada es menos convincente.
En los ejemplos anteriores, me estoy configurando
translatesAutosizingMaskIntoConstraints
parafalse
definir las restricciones yo mismo. Obviamente, puede dejartranslatesAutosizingMaskIntoConstraints
comotrue
y establecer tanto elframe
como elautosizingMask
para las vistas que agregue, si lo prefiere.Consulte las revisiones anteriores de esta respuesta para las versiones de Swift 3 y Swift 2 .
fuente
ViewController
ciclo de vida del incrustado . ElViewController
ciclo de vida del incrustado por Interface Builder es normal, pero el agregado mediante programación no tieneviewDidAppear
niviewWillAppear(_:)
niviewWillDisappear
.ViewController
'sviewDidAppear
que se llama en su matriz deviewDidLoad
, en lugar de durante su del padreviewDidAppear
viewDidAppear
, [pero] niviewWillAppear(_:)
niviewWillDisappear
". Loswill
métodos de aparecer se llaman correctamente en ambos escenarios. Uno debe llamardidMove(toParentViewController:_)
al hacerlo mediante programación, aunque, de lo contrario, no lo harán. Respecto al momento de la aparición. métodos, se llaman en la misma secuencia en ambos sentidos. Lo que sí difiere, sin embargo, es el tiempo deviewDidLoad
, porque con la inserción, se carga antesparent.viewDidLoad
, pero con la programática, como era de esperar, ocurre duranteparent.viewLoadLoad
.translatesAutoresizingMaskIntoConstraints = false
. No sé por qué es necesario o por qué hace que las cosas funcionen, pero gracias por incluirlo en su respuesta.La respuesta de @ Rob en Swift 3:
fuente
Detalles
Solución
Uso
Muestra completa
Resultados
fuente
tableViewController
unviewController
pero no puedo establecer el título del primero. No sé si es posible hacerlo. He publicado esta pregunta . Es amable de su parte si le echa un vistazo.Aquí está mi código en swift 5.
}
Uso
Utilice la otra función de incrustación con el controlador de vista sin guión gráfico.
fuente
removeFromParent
llamada evita, ¿cómo enmendaría su clase para permitir esto?