Eu tenho um UIView que é colocado na tela por meio de várias restrições. Algumas das restrições são propriedade do superview, outras são propriedade de outros ancestrais (por exemplo, talvez a propriedade view de um UIViewController).
Quero remover todas essas restrições antigas e colocá-las em algum lugar novo usando novas restrições.
Como posso fazer isso sem criar um IBOutlet para cada restrição e ter que lembrar qual visualização possui essa restrição?
Para elaborar, a abordagem ingênua seria criar um monte de IBOutlets para cada uma das restrições e envolveria códigos de chamada, como:
[viewA removeConstraint:self.myViewsLeftConstraint];
[viewB removeConstraint:self.myViewsTopConstraint];
[viewB removeConstraint:self.myViewsBottomConstraint];
[self.view removeConstraint:self.myViewsRightConstraint];
O problema com esse código é que mesmo no caso mais simples, eu precisaria criar 2 IBOutlets. Para layouts complexos, isso pode facilmente chegar a 4 ou 8 IBOutlets necessários. Além disso, eu precisaria garantir que minha chamada para remover a restrição seja feita na visualização adequada. Por exemplo, imagine que myViewsLeftConstraint
é propriedade de viewA
. Se eu ligasse acidentalmente [self.view removeConstraint:self.myViewsLeftConstraint]
, nada aconteceria.
Observação: o método constraintsAffectingLayoutForAxis parece promissor, mas destina-se apenas a fins de depuração.
Update: Muitas das respostas que eu estou recebendo acordo com self.constraints
, self.superview.constraints
ou alguma variante das pessoas. Essas soluções não funcionarão, pois esses métodos retornam apenas as restrições pertencentes à visualização, não aquelas que afetam a visualização.
Para esclarecer o problema com essas soluções, considere esta hierarquia de visualização:
- Avô
- Pai
- Eu
- Filho
- Filha
- Irmão
- Eu
- Tio
- Pai
Agora imagine que criamos as seguintes restrições e sempre as anexamos ao ancestral comum mais próximo:
- C0: Me: mesmo top que Son (propriedade de mim)
- C1: Me: largura = 100 (propriedade de mim)
- C2: Eu: mesma altura do irmão (propriedade do pai)
- C3: Eu: mesmo top que o tio (propriedade do avô)
- C4: Eu: igual à esquerda do avô (propriedade do avô)
- C5: Irmão: igual à esquerda do Pai (propriedade do Pai)
- C6: Tio: igual à esquerda do Avô (propriedade do Avô)
- C7: Filho: igual à filha (propriedade de mim)
Agora imagine que queremos remover todas as restrições que afetam Me
. Qualquer solução adequada deve remover [C0,C1,C2,C3,C4]
e nada mais.
Se eu usar self.constraints
(onde self sou eu), vou conseguir [C0,C1,C7]
, uma vez que essas são as únicas restrições que tenho . Obviamente, não seria suficiente removê-lo, pois está faltando [C2,C3,C4]
. Além disso, ele está removendo C7
desnecessariamente.
Se eu usar self.superview.constraints
(onde eu sou eu), vou conseguir [C2,C5]
, uma vez que essas são as restrições de propriedade do pai. Obviamente, não podemos remover tudo isso, pois não tem nenhuma C5
relação com Me
.
Se eu usar grandfather.constraints
, vou conseguir [C3,C4,C6]
. Novamente, não podemos remover todos eles, pois C6
devem permanecer intactos.
A abordagem de força bruta consiste em percorrer cada um dos ancestrais da visualização (incluindo ela mesma) e ver se firstItem
ou secondItem
são a própria visualização; em caso afirmativo, remova essa restrição. Isso levará a uma solução correta, retornando [C0,C1,C2,C3,C4]
, e apenas essas restrições.
No entanto, espero que haja uma solução mais elegante do que ter que percorrer toda a lista de ancestrais.