Какие основные API используются для создания анимаций в UIKit?

Ответ

Анимации в UIKit работают путем плавного изменения анимируемых свойств UIView или ее слоя CALayer с течением времени. Основные API:

1. UIView.animate (Классический API) Простой метод для анимации нескольких свойств одновременно.

UIView.animate(withDuration: 0.3,
               delay: 0.0,
               options: [.curveEaseInOut]) {
    // Изменяемые свойства
    view.alpha = 0.0
    view.frame.origin.y += 50
    view.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
} completion: { finished in
    // Действие по завершении
    view.removeFromSuperview()
}

2. UIViewPropertyAnimator (iOS 10+, Гибкий и контролируемый) Позволяет интерактивно управлять анимацией (пауза, отмена, изменение скорости).

let animator = UIViewPropertyAnimator(duration: 0.5,
                                      dampingRatio: 0.7) {
    view.frame.origin.x = 200
}
// Добавление этапов анимации
animator.addAnimations { view.alpha = 0.5 }
// Запуск
animator.startAnimation()
// Возможность паузы и отмены: animator.pauseAnimation(), animator.stopAnimation(true)

3. Core Animation (CALayer, для сложных и производительных анимаций) Прямая работа с графическим слоем. Позволяет анимировать свойства, недоступные для UIView.

let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.fromValue = 0
animation.toValue = CGFloat.pi * 2
animation.duration = 1.0
animation.repeatCount = .infinity
view.layer.add(animation, forKey: "spinAnimation")

Ключевые принципы:

  • Анимируемые свойства: frame, bounds, center, alpha, transform, backgroundColor.
  • Производительность: Анимации выполняются в отдельном потоке рендеринга и используют аппаратное ускорение.
  • Избегайте анимации frame вместе с Auto Layout. Вместо этого анимируйте константы constraints или используйте transform.
  • Для сложных последовательностей и переходов между контроллерами используйте UIViewControllerTransitioningDelegate.

Ответ 18+ 🔞

Да ты посмотри, какие у нас тут анимации в UIKit, блядь! Это ж целая наука, сука, не хухры-мухры. Сидишь такой, думаешь: "О, сейчас плавненько сделаю, красиво будет". А потом бац — и всё ебнулось, потому что не ту кнопку нажал. Но я тебе сейчас, как на духу, всё разложу, чтобы ты не облажался, как я в тот раз, когда пол-ночи дебажил вращение квадрата, который упорно не хотел вращаться, а только дергался, как будто его током хуярит.

1. UIView.animate (Старый добрый дедовский метод) Это как на Запорожце ехать: просто, надёжно, но кондиционера нет, блядь. Зато работает везде и всегда.

UIView.animate(withDuration: 0.3,
               delay: 0.0,
               options: [.curveEaseInOut]) {
    // Тут ты меняешь что хочешь
    view.alpha = 0.0
    view.frame.origin.y += 50
    view.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
} completion: { finished in
    // А вот тут уже всё, приехали
    view.removeFromSuperview()
}

Вот видишь? Написал и забыл. Оно само всё сделает. Главное, вьюху не трогай в другом месте, пока она анимируется, а то получишь пиздюлину от системы в виде артефактов.

2. UIViewPropertyAnimator (iOS 10+, Продвинутая хуйня) А это уже как на Tesla с автопилотом. Запустил и можешь руль покручивать на ходу, скорость менять, а то и вовсе нахуй отменить.

let animator = UIViewPropertyAnimator(duration: 0.5,
                                      dampingRatio: 0.7) {
    view.frame.origin.x = 200
}
// Хочешь ещё анимаций поверх? Без проблем!
animator.addAnimations { view.alpha = 0.5 }
// Поехали!
animator.startAnimation()
// А потом можешь сказать "стой, бля!" — animator.pauseAnimation()
// Или "да пошло всё нахуй!" — animator.stopAnimation(true)

Штука мощная, но и ответственности больше. Не накосячь, а то анимация уедет, а вьюха останется где-то посередине, выглядывая из-за угла, как полупидор.

3. Core Animation (CALayer, Для настоящих гурманов и мазохистов) Это когда тебе мало просто двигать квадратик. Хочется, чтобы он вращался по спирали, пульсировал всеми цветами радуги и при этом ещё и тень отбрасывал, которая моргает в такт музыке. Лезешь тогда прямо в кишки, в слой.

let animation = CABasicAnimation(keyPath: "transform.rotation.z")
animation.fromValue = 0
animation.toValue = CGFloat.pi * 2
animation.duration = 1.0
animation.repeatCount = .infinity
view.layer.add(animation, forKey: "spinAnimation")

Вот тут, блядь, главное — ключевой путь (keyPath) правильно указать. Напишешь "transform.rotation.y" вместо "transform.rotation.z" — и будет твоя вьюха кувыркаться, как угорелая, а не крутиться волчком. Сам так попадал, ебать стыдно было.

Запомни раз и навсегда, чтобы не было мучительно больно:

  • Что можно двигать: frame, bounds, center, alpha, transform, backgroundColor. Всё остальное — это уже танцы с бубном и прямой путь в CALayer.
  • Производительность: Оно всё летает, потому что железо делает. Не парься. Но если начнёшь в основном потоке хуйню какую-то считать во время анимации — получишь фризы и будет тебе пиздец, а пользователь уйдёт.
  • Самая популярная хуйня: Никогда, слышишь, НИКОГДА не анимируй frame у вьюхи, которая живёт по Auto Layout! Она тебе потом такую месть устроит, мама не горюй. Либо анимируй константы констрейнтов, либо юзай transform — это святое.
  • Если захотелось сделать переход между экранами не как у всех пидоров, а с изюминкой — готовься к UIViewControllerTransitioningDelegate. Это отдельный ад, но когда получится — чувствуешь себя богом интерфейсов, ёпта.