У меня есть UIView, который размещается на экране с помощью нескольких ограничений. Некоторые из ограничений принадлежат супервизору, другие принадлежат другим предкам (например, возможно, свойство представления UIViewController).
Я хочу удалить все эти старые ограничения и поместить их в новое место, используя новые ограничения.
Как я могу сделать это, не создавая IBOutlet для каждого ограничения и не запоминая, какое представление владеет указанным ограничением?
Чтобы уточнить, наивный подход заключался бы в создании группы IBOutlets для каждого из ограничений, а затем включал бы вызывающий код, например:
[viewA removeConstraint:self.myViewsLeftConstraint];
[viewB removeConstraint:self.myViewsTopConstraint];
[viewB removeConstraint:self.myViewsBottomConstraint];
[self.view removeConstraint:self.myViewsRightConstraint];
Проблема с этим кодом в том, что даже в простейшем случае мне нужно было бы создать 2 IBOutlet. Для сложных макетов это может легко достичь 4 или 8 требуемых IBOutlets. Кроме того, мне нужно будет убедиться, что мой вызов для удаления ограничения вызывается в правильном представлении. Например, представьте, что myViewsLeftConstraint
это принадлежит viewA
. Если бы я случайно позвонил [self.view removeConstraint:self.myViewsLeftConstraint]
, ничего бы не случилось.
Примечание . Метод constraintsAffectingLayoutForAxis выглядит многообещающим, но предназначен только для целей отладки.
Обновление: Многие из ответов я получаю дело с self.constraints
, self.superview.constraints
или каким - либо вариантом из них. Эти решения не будут работать, поскольку эти методы возвращают только ограничения, принадлежащие представлению, а не те, которые влияют на представление.
Чтобы прояснить проблему с этими решениями, рассмотрим эту иерархию представлений:
- Дедушка
- Отец
- мне
- Сын
- Дочь
- Родной брат
- мне
- Дядя
- Отец
Теперь представьте, что мы создаем следующие ограничения и всегда прикрепляем их к их ближайшему общему предку:
- C0: Я: такой же топ, что и Сын (принадлежит мне)
- C1: Me: width = 100 (принадлежит мне)
- C2: Я: одного роста с братом (принадлежит отцу)
- C3: Я: такая же вершина, как у дяди (принадлежит дедушке)
- C4: Я: то же самое, что и дедушка (принадлежит дедушке)
- C5: Брат: тот же, что и отец (принадлежит отцу)
- C6: Дядя: то же самое, что и дедушка (принадлежит дедушке)
- C7: Сын: такой же, как и дочь (принадлежит Мне)
Теперь представьте, что мы хотим удалить все влияющие ограничения Me
. Любой правильный раствор должен удалять [C0,C1,C2,C3,C4]
и ничего больше.
Если я использую self.constraints
(где self - это Я), я получу [C0,C1,C7]
, поскольку это единственные ограничения, которыми я владею . Очевидно, этого было бы недостаточно, так как он отсутствует [C2,C3,C4]
. Кроме того, он удаляется C7
без надобности.
Если я использую self.superview.constraints
(где я - это Я), я получу [C2,C5]
, поскольку это ограничения, принадлежащие Отцу. Очевидно, мы не можем удалить все это, поскольку C5
это совершенно не связано с Me
.
Если воспользуюсь grandfather.constraints
, получу [C3,C4,C6]
. Опять же, мы не можем удалить все это, поскольку они C6
должны остаться нетронутыми.
Подход грубой силы состоит в том, чтобы перебирать каждого из предков представления (включая его самого) и проверять, является ли само представление firstItem
или оно secondItem
есть; если да, удалите это ограничение. Это приведет к правильному решению, возврату [C0,C1,C2,C3,C4]
и только этим ограничениям.
Однако я надеюсь, что есть более элегантное решение, чем необходимость перебирать весь список предков.