Опишите цикл раскладки: setNeedsLayout, layoutSubviews, updateConstraints.
Три фазы и их направление
Цикл выполняется на каждом проходе run loop перед отрисовкой кадра (в CATransaction commit), только для view, помеченных «грязными».
- Update constraints — проход снизу вверх (от листьев к корню). Вызывается
updateConstraints()у view, для которых былsetNeedsUpdateConstraints(). Это место, где вы пакетно меняете/создаёте констрейнты; саму систему уравнений решает движок. Apple рекомендует переопределятьupdateConstraintsтолько для производительности, когда изменений много; в обычных случаях констрейнты меняют прямо там, где произошло событие. - Layout — проход сверху вниз (от корня к листьям). Движок решает систему и вызывает
layoutSubviews(): view получает свойframeи расставляет subviews.setNeedsLayout()помечает view на следующий проход,layoutIfNeeded()выполняет layout немедленно (так работает анимация констрейнтов). У контроллера вокруг этого —viewWillLayoutSubviews/viewDidLayoutSubviews. - Display — проход сверху вниз.
setNeedsDisplay()помечает слой, и вызываетсяdraw(_:)/display(_:). Изменениеframeне вызывает перерисовку автоматически, еслиcontentModeне.redraw.
Продолжение ответа с кодом и уточняющими вопросами интервьюера — в приложении DevPrep.
Полный ответ — в DevPrep