Что происходит с ограничениями при удалении представления

109

У меня простой вопрос, но я не смог найти никакой информации в документации.

Что происходит с ограничениями макета, когда представление удаляется из иерархии представлений (или перемещается в другое представление)?

Например, у нас есть контейнер Cс подпредставлениями Aи B. Контейнер Cимеет некоторые ограничения. Потом звоним [A removeFromSuperview]. Что происходит с ограничениями для A?

Что же произойдет , если мы добавим Aк Cснова?

Султан
источник

Ответы:

118

Ограничения сняты. Если вы снова добавите A, вам придется создать для него новые ограничения, или, если вы сохраните ограничения перед удалением A, вы можете добавить их обратно. Когда я делаю что-то подобное, я сохраняю такие ограничения для представления с именем 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
источник
7
Можно ли найти этот факт где-нибудь в документации? Я вам верю, но, как ни странно, нигде не упоминается.
Sulthan
2
Здравый смысл заключается в том, что ограничения действительно удаляются вместе с представлением. Если бы это было не так, как система макета смогла бы их оценить в будущем проходе?
Майк Поллард,
6
Каким бы очевидным ни был этот ответ, он все же был чрезвычайно полезен!
race_carr
1
@pnollet, я не знаю, почему автор этого вопроса сделал то, что сделал. Я зарегистрировал это, чтобы проверить, и когда я удаляю подпредставление и проверяю ограничения надпредставления, те ограничения, которые относились к удаленному подпредставлению, исчезают.
rdelmar
4
@ Firo, я уверен, что они должны быть удалены, поэтому, если они не в iOS 6, вероятно, это ошибка. Кстати, в документе для метода removeFromSuperview говорится: «Вызов этого метода удаляет все ограничения, которые относятся к удаляемому представлению или относятся к любому представлению в поддереве удаляемого представления».
rdelmar
41

Поскольку у меня тоже был этот вопрос, я просто проверил Apple Docs, и оказалось, что это задокументировано, что ограничения удалены.

В документации для метода UIView removeFromSuperview указано:

Вызов этого метода удаляет все ограничения, которые относятся к удаляемому представлению или относятся к любому представлению в поддереве удаляемого представления.

Я не уверен, было ли это задокументировано в прошлом году, когда был опубликован исходный вопрос, но я просто подумал, что поделюсь этой информацией на случай, если она кому-то понадобится ...

Эван Стоун
источник
Огромное спасибо за добавление прямо из документа
Esko918
3

Однако имейте в виду, что если у вас есть два независимых родительских представления A и B и подпредставление C, где C в настоящее время является подпредставлением A с соответствующими ограничениями, то вызов [B addSubview: C] НЕ удалит никаких ограничений, относящихся к A и C, и автоматическая компоновка начнет генерировать исключения, потому что эти ограничения больше не относятся к представлениям в той же иерархии.

Вам нужно будет явно вызвать [C removeFromSuperview], чтобы удалить ограничения, прежде чем добавлять C к B.

Это верно для Mac OS X - я не проверял iOS

Мартин Редингтон
источник
Интересный! Откуда у вас эта информация? В документации для addSubview такое поведение не упоминается. Я спрашиваю, потому что в настоящее время у меня есть спорадическое исключение при удалении контроллера представления, в котором указано «Невозможно установить ограничение на представление» - чего я не делаю.
JimmyB
2

Ограничения также снимаются, когда вы [A removeFromSuperview]

Они забыты, и добавление A к C снова не добавляет ограничений.

Майк Поллард
источник
0

Они тоже удаляются, можно сделать простой тест. Выберите представление SUBVIEW и создайте ограничения, которые ограничивают SUBVIEW, чтобы он следовал за изменением размера его суперпредставления (например, прикрепленным к краям супервизора). Для этого вы добавляете SUBVIEW в качестве подпредставления к этому CONTAINERVIEW и добавляете в качестве ограничений что-то вроде этого:
V: | - [SUBVIEW] - |
H: | - [ПОДРОБНЕЕ] - |
Эти ограничения должны быть добавлены в супервизор SUBVIEW, таким образом CONTAINERVIEW.
Если вы удалите SUBVIEW, просто проверив все ограничения CONTAINERVIEW, вы увидите, что двух больше нет.

Андреа
источник
0

Этот вопрос также может быть подтвержден конструктором интерфейсов. Когда перетащите и опустите UIViewна ViewControllerдобавление ограничений, а затем удалите UIView, вы увидите, что синие ограничения исчезнут.

Уильям Ху
источник
4
Раскадровка ничего не доказывает о том, как будет происходить поведение во время выполнения. Раскадровка может делать все, что угодно!
mxcl