Cosa succede con i vincoli quando una vista viene rimossa


109

La domanda che ho è semplice ma non sono riuscito a trovare alcuna informazione nella documentazione.

Cosa succede con i vincoli di layout quando una vista viene rimossa dalla gerarchia della vista (o spostata in un'altra vista)?

Ad esempio, disponiamo di un contenitore Ccon viste secondarie Ae B. Il contenitore Ccontiene alcuni vincoli. Allora chiamiamo [A removeFromSuperview]. Cosa succede con i vincoli per A?

Cosa succede se aggiungiamo Adi Cnuovo?

Risposte:


118

I vincoli vengono rimossi. Se aggiungi di nuovo A, dovrai creare nuovi vincoli per esso, oppure se salvi i vincoli prima di rimuovere A, puoi aggiungerli di nuovo. Quando faccio qualcosa di simile, salvo i vincoli come questo per una vista chiamata 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];
    }
}

7
Questo fatto può essere trovato da qualche parte nella documentazione? Ti credo ma sembra strano che il fatto non sia menzionato da nessuna parte.
Sulthan

2
È buon senso che i vincoli vengano rimossi insieme alla vista davvero. Se non lo fossero, come potrebbe il sistema di layout valutarli in un futuro passaggio?
Mike Pollard

6
Per quanto ovvia possa sembrare questa risposta, è stata comunque estremamente utile!
race_carr

1
@pnollet, non so perché il poster in quella domanda ha fatto quello che ha fatto. Ho registrato questo per verificarlo, e quando rimuovo una sottoview e controllo i vincoli sulla superview, quei vincoli che riguardavano la sottoview rimossa sono spariti.
rdelmar

4
@Firo, sono sicuro che dovrebbero essere rimossi, quindi se non sono in iOS 6, probabilmente è un bug. A proposito, il documento per il metodo removeFromSuperview dice: "Chiamare questo metodo rimuove tutti i vincoli che fanno riferimento alla vista che stai rimuovendo o che fanno riferimento a qualsiasi vista nella sottostruttura della vista che stai rimuovendo".
rdelmar

41

Dato che anch'io avevo questa domanda, ho controllato l'Apple Docs solo per i calci, e risulta che è documentato che i vincoli vengono rimossi.

La documentazione per il metodo UIView removeFromSuperview afferma:

La chiamata a questo metodo rimuove tutti i vincoli che fanno riferimento alla visualizzazione che si sta rimuovendo o che fanno riferimento a qualsiasi visualizzazione nella sottostruttura della visualizzazione che si sta rimuovendo.

Non sono sicuro che questo sia stato documentato l'anno scorso quando è stata pubblicata la domanda originale, ma ho pensato di condividere queste informazioni nel caso qualcuno ne avesse bisogno ...


Fantastico grazie per aver aggiunto questo direttamente dal documento
Esko918

3

Tieni presente, tuttavia, che se hai due viste principali indipendenti A e B, e una sottoview C, dove C è attualmente una sottoview di A, con i vincoli appropriati, quella chiamata [B addSubview: C] NON cancellerà alcun vincolo relativo ad A e C, e il layout automatico inizierà a generare eccezioni, perché quei vincoli non si riferiscono più alle viste nella stessa gerarchia.

Dovrai chiamare esplicitamente [C removeFromSuperview] per rimuovere i vincoli, prima di aggiungere C a B.

Questo è vero su Mac OS X: non ho controllato iOS


Interessante! Dove hai preso queste informazioni? I documenti per addSubview non menzionano questo comportamento. Lo chiedo perché al momento ho un'eccezione sporadica, quando rimuovo un controller di visualizzazione, che indica "Impossibile installare il vincolo sulla visualizzazione", cosa che non sto facendo.
JimmyB

2

I vincoli vengono rimossi anche quando si [A removeFromSuperview]

Vengono dimenticati e l'aggiunta di A a C non aggiunge alcun vincolo.


0

Anche loro vengono rimossi, puoi fare un semplice test. Prendi una vista SUBVIEW e crea vincoli che vincolano SUBVIEW a seguire il suo ridimensionamento della superview (come attaccata ai bordi della superview). Per farlo, aggiungi SUBVIEW come subview a CONTAINERVIEW e aggiungi come vincoli qualcosa del genere:
V: | - [SUBVIEW] - |
H: | - [visualizzazione secondaria] - |
Questi vincoli dovrebbero essere aggiunti a SUBVIEW superview, quindi CONTAINERVIEW.
Se rimuovi SUBVIEW semplicemente controllando tutti i vincoli CONTAINERVIEW potresti vedere che due non sono più in giro.


0

Questa domanda può anche essere dimostrata dal costruttore di interfacce. Quando si trascina e rilascia un UIViewsui ViewControllervincoli di aggiunta, quindi si rimuove il UIView, è possibile vedere i vincoli blu scomparire.


4
Storyboard non dimostra nulla su come si verificherà il comportamento in fase di esecuzione. Storyboard può fare quello che vuole!
mxcl
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.