Как анимировать UIView простым способом
Что проверяют
Знаете ли вы базовое API анимаций UIKit и что происходит под ним. Следом обычно спрашивают, как анимировать изменение констрейнтов или как сделать анимацию, которую пользователь может прервать жестом.
Как отвечать
Простой способ это блочный API UIView.animate(withDuration:delay:options:animations:completion:). Внутри блока вы задаёте конечные значения свойств, а UIKit строит анимацию Core Animation от текущего состояния к новому. Кривая по умолчанию curveEaseInOut.
- что анимируется:
frame,bounds,center,transform,alpha,backgroundColor.isHiddenне анимируется, для плавного исчезновения меняютalpha; - Auto Layout:
frameвручную не трогают. Меняютconstantу констрейнта, а в блоке анимации вызываютlayoutIfNeeded()у родительского view; - пружина: вариант с
usingSpringWithDamping:initialSpringVelocity:, а в новых версиях UIKit есть и форма с параметрамиspringDurationиbounce, как в SwiftUI; - смена содержимого:
UIView.transition(with:duration:options:animations:)с.transitionCrossDissolve, например для замены картинки или текста; - ключевые кадры:
animateKeyframesдля последовательности шагов в одной анимации; UIViewPropertyAnimator: когда анимацию нужно ставить на паузу, разворачивать или вести за пальцем черезfractionComplete.
Параметр finished в completion показывает, дошла ли анимация до конца или её прервали. На него стоит смотреть перед тем, как запускать следующий шаг.
Где спотыкаются
Анимируют frame у view, которое расставлено констрейнтами. Анимация проходит, а на следующем проходе layout возвращает всё на место.
Вызывают layoutIfNeeded() у самого анимируемого view, а не у его родителя. Изменение констрейнта затрагивает раскладку родителя, и анимации не видно.
Не знают, что во время блочной анимации view не принимает касания, пока не передан .allowUserInteraction, а касания проверяются по конечной позиции, а не по той, что видна на экране.