Autolayout: updateConstraints не получает вызов при изменении ориентации

Я изучаю, как работает Auto layout в iOS. Для этого я создал пример приложения с одним представлением, которое имеет один контроллер представления (который является исходным контроллером представления) и одно пользовательское представление (назовем его образцом представления). Я добавил образец представления в контроллер представления в Main.storyboard с ограничениями автоматического макета. Я добавил кнопку и метку в Sample View с ограничениями автоматического макета. Я переопределяю метод layoutSubviews и updateConstraints в SampleView.m. Эти переопределенные методы ничего не делают, кроме как вызывают свою суперреализацию. Я добавил точку останова к обоим этим методам и начал отлаживать приложение. Ниже приведены мои наблюдения

  1. Я обнаружил, что updateConstraints вызывается перед методом layoutSubviews в SampleView. Однако я прочитал несколько сообщений/ответов, где упоминается, что layoutSubviews вызывается перед updateConstraints. Теперь я в замешательстве, каков правильный механизм? вызывается ли updateConstraint перед layoutSubviews или наоборот. Как работает система автоматической разметки?

  2. Когда я поворачиваю устройство с портретной на альбомную или с альбомной на портретную, я обнаружил, что метод updateConstraints SampleView не вызывается автоматически (однако метод layoutSubviews вызывается автоматически), в то время как я прочитал несколько сообщений/ответов, в которых говорится, что при вращении Метод updateConstraints вызывается автоматически. Я снова запутался, что из этого правда?

  3. Если метод updateConstrains не вызывается автоматически при изменении ориентации, то как мы можем вызвать метод updateConstraint для всех представлений в иерархии представлений при изменении ориентации? Будет ли вызов setNeedsUpdateConstraint для большинства родительских представлений вызывать updateConstraint для всех дочерних представлений этого представления?


person Mousam    schedule 14.07.2015    source источник


Ответы (2)


Процесс компоновки обычно выглядит следующим образом:

Первый шаг: обновление ограничений происходит снизу вверх. Инициируется вызовом [view setNeedsUpdateConstraints], переопределяет [view updateConstraints] для пользовательских представлений. Этот шаг устраняет ограничения.

Второй шаг: макет выполняется сверху вниз. Запускается вызовом [view setNeedsLayout], [view layoutIfNeeded], переопределением [view layoutSubviews] для пользовательских представлений. Когда вызывается layoutSubviews, у нас есть фреймы.

Третий шаг: отображение сверху вниз. Запускается вызовом [view setNeedsDisplay], переопределяет [view drawRect:] для пользовательских представлений.

so,

  1. updateConstraints происходит до layoutSubviews. Ограничения — это в основном объекты, добавленные в родительское представление представления, описывающие, как размещать подпредставления родительского представления. Таким образом, вам необходимо обновить ограничения до того, как будет выполнен макет.

  2. При изменении ориентации ограничения не изменились, поэтому я думаю, что updateConstraints вызываться не будет.

  3. Как мы можем вызвать метод updateConstraint для всех представлений в иерархии представлений при изменении ориентации? Ограничения не нужно обновлять, потому что они определяют, как представления должны быть связаны друг с другом. Вместо этого при изменении ориентации будет обновляться фрейм самого верхнего вида (UIWindow), поэтому все его подвиды должны обновить свой фрейм, чтобы соответствовать ограничениям, которые вы установили ранее.

Если я ошибаюсь, поправьте меня :)

person Jakehao    schedule 14.07.2015
comment
@Mousam по поводу вашего старого вопроса здесь, я добавил несколько мыслей - надеюсь, это поможет! - person Fattie; 06.08.2019

Это очень запутанно.

Один из способов взглянуть на это так: у вас, скорее всего, будут различные ограничения для разных ориентаций.

И это играет со всей системой черт в iOS. (С которым вы должны быть знакомы на 1000%, чтобы даже разобраться с этой проблемой! :O)

Рассмотрим невероятно настраиваемый вид...

(Примечание: почти наверняка это означает вид, который непрерывно анимируется при изменении размера, что, как правило, является всей точкой такого вида.)

В невероятно индивидуальном представлении вы будете постоянно "изменять ограничения"....

Но это означает, что вы будете изменять... "ограничения для одной ориентации" (даже если они, как оказалось, в данный момент не используются)... И... вы будете изменять "ограничения для другой ориентации" (даже если те, как оказалось, в данный момент не используются).

Вы используете updateConstraints() для изменения «всех» ограничений (в большинстве ситуаций, когда это возникает, на постоянной основе на основе анимации/изменения размера представления) — и это означает все ограничения. ограничения для всех вариаций черт, всех времени - !

Это один из важных способов взглянуть на проблему!

person Fattie    schedule 06.08.2019