В чем отличие UIView и CALayer, как они связаны и кто за что отвечает?
Что проверяют
Понимаете ли вы, как UIKit устроен поверх Core Animation, и где заканчивается ответственность вью и начинается слой. Следом обычно спрашивают про неявные анимации и про то, почему тень или скругление тормозят список.
Как отвечать
Каждый UIView опирается на CALayer: слой создаётся вместе с вью и доступен через свойство layer, а его класс задаётся переопределением layerClass (например, CAGradientLayer или CAShapeLayer). Вью при этом служит делегатом своего слоя.
Разделение ответственности:
- UIView: наследник
UIResponder, поэтому касания, жесты, цепочка респондеров, Auto Layout, доступность, trait collection; - CALayer: хранит содержимое и геометрию, отвечает за отрисовку и анимации. Содержимое кэшируется как растровое изображение и компонуется на GPU отдельным процессом рендеринга;
- общие свойства:
frame,bounds,center,alpha,transformу вью по сути прокидываются в слой (alphaстановитсяopacity); - только у слоя:
cornerRadius,borderWidth, тени,mask,anchorPoint, трёхмерныйCATransform3D.
У слоёв своя полноценная иерархия через sublayers и addSublayer(_:), и иерархия вью ей зеркально соответствует. Слой без вью легче, но не получает касаний и не участвует в Auto Layout.
Сильная деталь для ответа: у самостоятельного слоя изменение анимируемого свойства по умолчанию анимируется неявно, примерно за четверть секунды. У слоя, который принадлежит вью, этого не происходит: вью как делегат возвращает пустое действие вне блока UIView.animate.
Где спотыкаются
Говорят, что слой не может содержать другие слои или сам обрабатывает касания. Обе вещи неверны: иерархия подслоёв есть, а событий нет.
Анимируют через CABasicAnimation, не меняя модельное значение, и после окончания слой прыгает назад. Лечат это fillMode = .forwards с isRemovedOnCompletion = false, хотя правильно выставить итоговое значение самому свойству.
Добавляют подслой и ждут, что Auto Layout подгонит его размер. Frame подслоя надо обновлять в layoutSubviews(), а тень задавать через shadowPath, иначе система вычисляет её форму по альфа-каналу отдельным проходом вне экрана.