Как используется layoutIfNeeded?

Когда и как используется layoutIfNeeded? Я знаю, что когда мы меняем макет представления, мы можем вызвать setNeedsLayout для обновления макета, но не уверены, когда следует использовать layoutIfNeeded.

ПРИМЕЧАНИЕ. Я использовал layoutIfNeeded в действительном коде, но забыл, в каком контексте он был использован.

Ответ 1

layoutIfNeeded заставляет приемник немедленно отображать свои подсмотры, если это необходимо.

Предположим, что вы переопределили layoutSubviews, и UIKit считает, что ваше представление требует макета по любой причине (например, вы вызывали setNeedsLayout при обработке какого-либо действия пользователя). Затем ваш пользовательский метод layoutSubviews будет вызываться немедленно, а не когда он будет обычно вызываться в обычной последовательности событий цикла выполнения UIKit (после обработки событий, но до drawRect:).

Пример того, почему вам может потребоваться вызвать layoutIfNeeded в пределах одного цикла запуска:

  • Вы изменяете размер пользовательского представления, содержащего представление таблицы с настраиваемой компоновкой. setNeedsLayout устанавливается так, что layoutSubviews будет вызываться позже.
  • Объект контроллера запрашивает представление таблицы для прокрутки к определенной ячейке при обработке пользовательского события.
  • Пользовательский вид выполняет пользовательский размер представления таблицы в layoutSubviews, который изменяет размер вида таблицы.

Проблема заключается в том, что контроллер запросил прокрутку таблицы (шаг 2), в представлении таблицы были устаревшие ограничения. Обновленные оценки будут установлены только в представлении таблицы позже (шаг 3). То, что контроллер хотел, чтобы просмотр таблицы мог прокручиваться, на самом деле не может быть видимым после завершения layoutSubviews. Тогда решение будет состоять в том, чтобы контроллер вызывал layoutIfNeeded в ситуациях, когда он знает, что это может произойти.

Ответ 2

setNeedsLayout на самом деле вызывает layoutIfNeeded, поэтому, если в вашем вызове setNeedsDisplay нет причин для вызова layoutIfNeeded. Таким образом setNeedsLayout является удобным методом для вызова layoutIfNeeded, который делает тяжелый подъем.