Подтвердить что ты не робот

Включить + Отключить ограничения автоматической компоновки

У меня есть простая (я думаю) проблема: у меня есть UIImageView, на который я установил несколько ограничений для раскадровки.

Иногда мне нужно отключить ограничения и установить его frame вручную, но позже я хочу снова включить эти ограничения и вернуть представление туда, где это было определено ограничениями,

Я думал, что смогу сделать это с чем-то вроде:

@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var constraint: NSLayoutConstraint!

func example() { 

    //to set its location and size manually
    imageView.removeConstraint(constraint) 
    imageView.frame = CGRectMake(...)

    //to cause it to return to its original position
    imageView.addConstraint(constraint) 

}

При этом, однако, я получаю ошибку 2015-08-26 01:14:55.417 Constraints[18472:923024] The view hierarchy is not prepared for the constraint: <NSLayoutConstraint:0x7fbb72815f90 V:[_UILayoutGuide:0x7fbb72814c20]-(100)-[UIImageView:0x7fbb72814540]>. Кто-нибудь знает, почему возникает эта ошибка?

Добавление ограничений вместо view путем вызова self.view.addConstraint(...) устраняет ошибку, но не возвращает изображение обратно туда, где оно должно быть.

Я замечаю, что мне даже не нужно удалять и деактивировать ограничения, чтобы иметь возможность установить кадр imageView без проблем, если я не вызываю setTranslatesAutoresizingMaskIntoConstraints(true).

Я уже видел этот вопрос, но ответ кажется излишне сложным, возможно устаревшим и даже неприменимым.

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

Попытка установить свойство active:

self.top.active = false
self.right.active = false
self.bottom.active = false
self.left.active = false

imageView.frame = CGRectMake(100, 100, 100, 100)

Это фактически приводит к тому, что imageView больше не отображается. (Если я не установил для всех свойств ограничений active значение false, однако imageView переместится в нужную позицию.

Реальная проблема заключается в том, что когда я пытаюсь вернуть представление изображения туда, где оно было, установив для всех свойств ограничений < active значение true, ничего не происходит - изображениеView остается там, где оно было (в этом case, как указано в imageView.frame = CGRectMake(100, 100, 100, 100).

Кроме того, согласно моему тестированию и Joachim Bøggild ответьте здесь, что если для свойства ограничения active установлено значение false, это ограничение становится равным нулю, и, следовательно, не может быть повторно активирована.

Добавление ограничений в массив и активация/деактивация их:

Интересно, что это вызывает почти те же проблемы, что и установка свойства active. Размещение всех ограничений в массиве array, а вызов NSLayoutConstraint.deactivateConstraints(array) приводит к исчезновению изображения. Кроме того, повторная активация ограничений позже с помощью NSLayoutConstraint.activateConstraints(array) не возвращает изображение в том месте, где оно должно - оно остается там, где оно было.

4b9b3361

Ответ 1

Ага!

Ограничения становятся nil (и, следовательно, не могут быть повторно активированы), как только их свойство active установлено в false. Создание сильных ссылок (спасибо, Caleb, для очистки номенклатуры) сохраняет их, чтобы они могли быть активированы и деактивированы по желанию.

Ответ 2

Если вы посмотрите на документы для NSLayoutConstraint, вы найдете раздел под названием Активация и деактивация ограничений, который описывает active, которое, в свою очередь, сообщает вам:

Вы можете активировать или деактивировать ограничение, изменив это свойство... Активация или деактивация вызовов ограничений addConstraint: и removeConstraint: в представлении, которое является ближайшим общим предком элементов, управляемых этим ограничением. Используйте это свойство вместо вызова addConstraint: или removeConstraint: напрямую.

Итак, как только у вас есть ссылка strong на рассматриваемое ограничение (например, у вас есть выход), вы можете просто установить для этого свойства active значение false (или NO в Obj-C) для отключения или true (или YES) для включения.

Ответ 3

Соедините Constraint как IBOutlet от раскадровки до ViewController и создайте Array add All constraint в массиве.

Деактивируйте эти ограничения, если они не используются.

Добавить ограничение всякий раз, когда используется.

NSLayoutConstraint *constraint1;
NSLayoutConstraint *constraint2;
NSLayoutConstraint *constraint3;
NSArray *arr = @[constraint1,constraint2,constraint3];
 [NSLayoutConstraint deactivateConstraints:arr];

//After deactivate constraint array add what ever frame you want to add

//Activate  lateroN
[NSLayoutConstraint activateConstraints:arr];