Какой метод UIKit вызывается синхронно: `setNeedsLayout` или `layoutIfNeeded`?

«Какой метод UIKit вызывается синхронно: `setNeedsLayout` или `layoutIfNeeded`?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Синхронно вызывается layoutIfNeeded.

Различие в поведении:

  • setNeedsLayout()асинхронный запрос. Он помечает представление как требующее обновления компоновки (layout). Сам пересчет произойдет в следующем цикле run loop. Это предпочтительный и эффективный способ запланировать обновление.
  • layoutIfNeeded()синхронный вызов. Он немедленно вызывает пересчет layout'а для представления и всех его subviews, если есть невыполненные изменения. Блокирует текущий поток до завершения вычислений.

Практическое применение layoutIfNeeded: Критически важен для анимации изменений Auto Layout constraints. Вызов внутри анимационного блока заставляет систему интерполировать между старым и новым layout'ом.

Пример (Анимация изменения констрейнта):

// 1. Планируем изменение (констрейнт активируется позже)
heightConstraint.constant = 200

// 2. В блоке анимации форсируем немедленный пересчет layout'а
UIView.animate(withDuration: 0.3) {
    // Без этого вызова анимации не будет, изменение применится позже
    self.view.layoutIfNeeded()
}

Почему так: setNeedsLayout только планирует работу, layoutIfNeeded — выполняет ее «здесь и сейчас».