O que acontece com as restrições quando uma visualização é removida

109

A pergunta que tenho é simples mas não consegui encontrar nenhuma informação na documentação.

O que acontece com as restrições de layout quando uma visualização é removida da hierarquia de visualização (ou movida para outra visualização)?

Por exemplo, vamos ter um container Ccom subvisualizações Ae B. O contêiner Ccontém algumas restrições. Então ligamos [A removeFromSuperview]. O que acontece com as restrições A?

O que acontece então se somarmos Aa Cde novo?

Sulthan
fonte

Respostas:

118

As restrições são removidas. Se você adicionar A novamente, terá que fazer novas restrições para ele ou, se salvar as restrições antes de remover A, poderá adicioná-las de volta. Quando faço algo assim, salvo as restrições como esta para uma visualização chamada 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
fonte
7
Esse fato pode ser encontrado em algum lugar da documentação? Eu acredito em você, mas parece estranho que o fato não seja mencionado em lugar nenhum.
Sulthan,
2
É senso comum que as restrições sejam realmente removidas junto com a visualização. Se não fossem, como o sistema de layout seria capaz de avaliá-los em uma passagem futura?
Mike Pollard
6
Por mais óbvio que essa resposta pareça, ela ainda foi extremamente útil!
race_carr
1
@pnollet, não sei por que o autor dessa pergunta fez o que fez. Eu registrei isso para verificar e, quando removo uma subvisualização e verifico as restrições na subvisualização, aquelas restrições que pertenciam à subvisualização removida desapareceram.
rdelmar de
4
@Firo, tenho certeza que eles devem ser removidos, então se eles não estiverem no iOS 6, provavelmente é um bug. BTW, o documento para o método removeFromSuperview diz: "Chamar este método remove todas as restrições que se referem à visualização que você está removendo ou que se referem a qualquer visualização na subárvore da visualização que você está removendo".
rdelmar
41

Como eu também tinha essa dúvida, verifiquei o Apple Docs apenas por diversão e descobri que está documentado que as restrições foram removidas.

A documentação para o método UIView removeFromSuperview afirma:

Chamar esse método remove todas as restrições que se referem à visualização que você está removendo ou que se referem a qualquer visualização na subárvore da visualização que você está removendo.

Não tenho certeza se isso foi documentado no ano passado, quando a pergunta original foi postada, mas pensei em compartilhar essas informações caso alguém precisasse ...

Evan Stone
fonte
Muito obrigado por adicionar diretamente do documento
Esko918
3

Esteja ciente, porém, que se você tiver duas visualizações pai independentes A e B, e uma subvisualização C, onde C é atualmente uma subvisão de A, com restrições apropriadas, que chamar [B addSubview: C] NÃO limpará quaisquer restrições relacionadas a A e C, e o layout automático começará a lançar exceções, porque essas restrições não estão mais relacionadas a visualizações na mesma hierarquia.

Você precisará chamar [C removeFromSuperview] explicitamente para remover as restrições, antes de adicionar C a B.

Isso é verdade no Mac OS X - eu não verifiquei o iOS

Martin Redington
fonte
Interessante! Onde você conseguiu essa informação? Os documentos para addSubview não mencionam esse comportamento. Estou perguntando porque atualmente tenho uma exceção esporádica, ao remover um controlador de exibição, que afirma 'Não é possível instalar a restrição no modo de exibição' - algo que não estou fazendo.
JimmyB de
2

As restrições também são removidas quando você [A removeFromSuperview]

Eles são esquecidos e adicionar A a C novamente não adiciona restrições.

Mike Pollard
fonte
0

Eles também são removidos, você pode fazer um teste simples. Escolha uma visão SUBVIEW e crie restrições que restrinjam SUBVIEW a seguir seu redimensionamento de superview (como anexado às bordas de superview). Para fazer isso, você adiciona SUBVIEW como uma subvisão a este CONTAINERVIEW e adiciona como restrições algo como:
V: | - [SUBVIEW] - |
H: | - [SUBVIEW] - |
Essas restrições devem ser adicionadas ao superview de SUBVIEW, ou seja, CONTAINERVIEW.
Se você remover SUBVIEW simplesmente checando todas as restrições CONTAINERVIEW, você verá que dois não estão mais por perto.

Andrea
fonte
0

Esta questão também pode ser comprovada pelo construtor de interface. Ao arrastar e soltar um UIViewnas ViewControllerrestrições de adição e depois remover o UIView, você pode ver as restrições azuis desaparecerem.

William Hu
fonte
4
O storyboard não prova nada sobre como o comportamento em tempo de execução ocorrerá. O Storyboard pode fazer o que quiser!
mxcl