Qué sucede con las restricciones cuando se elimina una vista

109

La pregunta que tengo es simple pero no pude encontrar ninguna información en la documentación.

¿Qué sucede con las restricciones de diseño cuando una vista se elimina de la jerarquía de vistas (o se mueve a otra vista)?

Por ejemplo, tengamos un contenedor Ccon subvistas Ay B. El contenedor Ctiene algunas limitaciones. Entonces llamamos [A removeFromSuperview]. ¿Qué pasa con las restricciones para A?

¿Qué pasa entonces si agregamos Ade Cnuevo?

Sulthan
fuente

Respuestas:

118

Se eliminan las restricciones. Si agrega A nuevamente, tendrá que hacer nuevas restricciones para él, o si guarda las restricciones antes de quitar A, puede agregarlas nuevamente. Cuando hago algo como esto, guardo las restricciones como esta para una vista llamada view1:

self.portraitConstraints = [NSMutableArray new];
for (NSLayoutConstraint *con in self.view.constraints) {
    if (con.firstItem == self.view1 || con.secondItem == self.view1) {
       [self.portraitConstraints addObject:con];
    }
}
rdelmar
fuente
7
¿Se puede encontrar este hecho en alguna parte de la documentación? Te creo, pero parece extraño que el hecho no se mencione en ninguna parte.
Sulthan
2
Es de sentido común que las restricciones se eliminen junto con la vista realmente. Si no lo fueran, ¿cómo podría el sistema de diseño evaluarlos en una pasada futura?
Mike Pollard
6
Por más obvia que parezca esta respuesta, ¡fue tremendamente útil!
race_carr
1
@pnollet, no sé por qué el cartel de esa pregunta hizo lo que hizo. He registrado esto para verificar, y cuando elimino una subvista y verifico las restricciones en la supervista, esas restricciones que pertenecían a la subvista eliminada desaparecen.
rdelmar
4
@Firo, estoy seguro de que se supone que deben eliminarse, así que si no están en iOS 6, probablemente sea un error. Por cierto, el documento del método removeFromSuperview dice: "Llamar a este método elimina cualquier restricción que se refiera a la vista que está eliminando, o que se refiere a cualquier vista en el subárbol de la vista que está eliminando".
rdelmar
41

Como también tenía esta pregunta, verifiqué los documentos de Apple solo por diversión, y resulta que está documentado que las restricciones se eliminaron.

La documentación del método removeFromSuperview de UIView indica:

Llamar a este método elimina cualquier restricción que se refiera a la vista que está eliminando o que se refiere a cualquier vista en el subárbol de la vista que está eliminando.

No estoy seguro de si esto se documentó el año pasado cuando se publicó la pregunta original, pero pensé en compartir esta información en caso de que alguien la necesitara ...

Evan Stone
fuente
Increíble gracias por agregar esto directamente del documento
Esko918
3

Sin embargo, tenga en cuenta que si tiene dos vistas principales independientes A y B, y una subvista C, donde C es actualmente una subvista de A, con las restricciones adecuadas, llamar a [B addSubview: C] NO eliminará ninguna restricción relacionada con A y C, y el diseño automático comenzará a generar excepciones, porque esas restricciones ya no se relacionan con las vistas en la misma jerarquía.

Deberá llamar a [C removeFromSuperview] explícitamente para eliminar las restricciones, antes de agregar C a B.

Esto es cierto en Mac OS X: no he comprobado iOS

Martin Redington
fuente
¡Interesante! ¿De dónde sacaste esta información? Los documentos de addSubview no mencionan este comportamiento. Lo pregunto porque actualmente tengo una excepción esporádica, al eliminar un controlador de vista, que dice 'No se puede instalar la restricción en la vista', algo que no estoy haciendo.
JimmyB
2

Las restricciones también se eliminan cuando [A removeFromSuperview]

Se olvidan y volver a agregar A a C no agrega restricciones.

Mike Pollard
fuente
0

También se eliminan, puede hacer una prueba simple. Elija una vista SUBVIEW y cree restricciones conjuntas que restrinjan SUBVIEW para seguir su cambio de tamaño de supervista (como adjunto a los bordes de supervista). Para hacer eso, agregue SUBVIEW como una subvista a este CONTAINERVIEW y agregue como restricciones algo como eso:
V: | - [SUBVIEW] - |
H: | - [SUBVIEW] - |
Estas restricciones deben agregarse a la supervista SUBVIEW, por lo tanto, CONTAINERVIEW.
Si elimina SUBVIEW simplemente marcando todas las restricciones de CONTAINERVIEW, podría ver que ya no hay dos.

Andrea
fuente
0

Esta pregunta también puede ser probada por el constructor de interfaces. Cuando arrastre y suelte a UIViewen las ViewControllerrestricciones de adición y luego elimine UIView, puede ver que las restricciones azules desaparecen.

William Hu
fuente
4
Storyboard no prueba nada sobre cómo ocurrirá el comportamiento en tiempo de ejecución. ¡Storyboard puede hacer lo que quiera!
mxcl