Ответ
Метод setNeedsLayout() — это запрос на асинхронное обновление макета (layout) для UIView. Он помечает представление как "грязное" (dirty), сообщая системе, что его frame или bounds устарели и должны быть пересчитаны в следующем цикле обновления интерфейса.
Ключевые особенности:
- Асинхронный: Не вызывает немедленного перерасчёта. Обновление произойдёт в следующем проходе run loop.
- Оптимизированный: Система объединяет несколько вызовов
setNeedsLayout()в одном цикле, предотвращая лишнюю работу. - Триггер для
layoutSubviews(): Основная задача — запланировать вызовlayoutSubviews()у этой вью и её сабвью.
Когда вызывать? После изменений, влияющих на геометрию вью:
// 1. Изменили констрейнты
myView.widthConstraint.constant = 100
myView.setNeedsLayout() // Запланировали обновление макета
// 2. Изменили frame или bounds (при ручном управлении)
mySubview.frame = newFrame
mySubview.setNeedsLayout()
// 3. Добавили/удалили сабвью
containerView.addSubview(newView)
containerView.setNeedsLayout()
Отличие от layoutIfNeeded():
setNeedsLayout()— отложенный запрос ("сделай позже").layoutIfNeeded()— немедленный вызовlayoutSubviews(), если макет помечен как "грязный". Используется, когда обновлённая геометрия нужна сразу (например, для анимации).// Анимация с изменением констрейнтов UIView.animate(withDuration: 0.3) { constraint.constant = 200 view.superview?.layoutIfNeeded() // Немедленный пересчёт для анимации }