Выполнение анимации iOS в представлениях с помощью UIKit и UIView
Выполнение анимации iOS в представлениях с помощью UIKit и UIView
Опубликовано: 2022-03-10
Краткое резюме ↬ Эта статья призвана стать учебником по анимации iOS, исчерпывающим образом описывающим различные способы ее создания. Мы начинаем с понимания основ анимации, переходим к базовым платформам, создаем один пример с использованием различных предлагаемых методов и, наконец, ищем способы настройки производительности.
Я работаю iOS-разработчиком уже более десяти лет и редко встречал статьи, в которых собраны все возможные способы выполнения анимации в iOS. Эта статья призвана стать учебником по анимации iOS с целью исчерпывающего описания различных способов сделать то же самое.
Учитывая обширность темы, мы бы осветили каждую часть лаконично на достаточно высоком уровне. Цель состоит в том, чтобы обучить читателя набору вариантов добавления анимации в его/ее приложение для iOS.
Прежде чем мы начнем с тем, связанных с iOS, давайте кратко рассмотрим скорость анимации.
Анимация со скоростью 60 кадров в секунду
Как правило, в видео каждый кадр представлен изображением, а частота кадров определяет количество перевернутых изображений в последовательности. Это называется «кадры в секунду» или FPS.
FPS определяет количество неподвижных изображений, перевернутых в течение секунды, что буквально означает, что чем больше количество изображений/кадров, тем больше деталей/информации отображается в видео. Это справедливо и для анимации.
FPS обычно используется для определения качества анимации. Существует распространенное мнение, что любая хорошая анимация должна работать со скоростью 60 кадров в секунду или выше — все, что ниже 60 кадров в секунду, будет выглядеть немного странно.
Хотите увидеть разницу между 30FPS и 60FPS? Проверь это!
Вы заметили разницу? Человеческие глаза определенно могут чувствовать дрожание при более низких частотах кадров. Следовательно, всегда рекомендуется убедиться, что любая созданная вами анимация соответствует основному правилу работы со скоростью 60 кадров в секунду или выше. Это делает его более реалистичным и живым.
Посмотрев на FPS, давайте теперь углубимся в различные основные фреймворки iOS, которые предоставляют нам способ выполнения анимации.
Еще после прыжка!Продолжить чтение ниже ↓
Основные рамки
В этом разделе мы коснемся фреймворков в iOS SDK, которые можно использовать для создания анимации представлений. Мы быстро пройдемся по каждому из них, объяснив их набор функций на соответствующем примере.
UIKit/UIView Анимации
UIView — это базовый класс для любого представления, отображающего содержимое в приложениях iOS.
UIKit, платформа, которая дает нам UIView, уже предоставляет нам некоторые базовые функции анимации, которые позволяют разработчикам достигать большего, делая меньше.
API UIView.animate — это самый простой способ анимации представлений, поскольку любые свойства представления можно легко анимировать, предоставляя значения свойств в блочном синтаксисе.
В анимациях UIKit рекомендуется изменять только анимационные свойства UIVIew, иначе будут последствия, когда анимация может привести к тому, что представление окажется в неожиданном состоянии.
анимация (withDuration: анимации: завершение)
Этот метод принимает продолжительность анимации, набор анимируемых изменений свойств представления, которые необходимо анимировать. Блок завершения дает обратный вызов, когда представление выполнено с выполнением анимации.
Практически любой вид анимации, такой как перемещение, масштабирование, вращение, затухание и т. д., можно реализовать с помощью этого единственного API.
Теперь представьте, что вы хотите анимировать изменение размера кнопки или хотите, чтобы конкретный вид увеличивал экран. Вот как мы можем это сделать с помощью UIView.animate API:
Мы вызываем метод UIView.animate с переданным ему значением продолжительности, которое показывает, как долго должна работать анимация, описанная внутри блока.
Мы устанавливаем новый кадр кнопки, который должен представлять конечное состояние анимации.
Мы устанавливаем центр кнопки с center ее супервида так, чтобы он оставался в центре экрана.
Приведенный выше блок кода анимации должен запускать анимацию смены кадра кнопки с текущего кадра:
Width = 0, Height = 0
К последнему кадру:
Width = Height = newButtonWidth
А вот как будет выглядеть анимация:
анимироватьWithDuration
Этот метод похож на расширение метода анимации, где вы можете делать все, что вы могли делать в предыдущем API, с добавлением некоторых физических поведений к анимации просмотра.
Например, если вы хотите добиться эффекта демпфирования пружины в анимации, которую мы сделали выше, тогда код будет выглядеть следующим образом:
duration Представляет продолжительность анимации, определяющую, как долго должен выполняться блок кода.
delay Представляет начальную задержку, которую мы хотим иметь перед началом анимации.
SpringWithDamping Представляет значение упругого эффекта, которым мы хотим, чтобы представление вело себя. Значение должно находиться в диапазоне от 0 до 1. Чем ниже значение, тем выше колебания пружины.
velocity Представляет скорость, с которой должна начинаться анимация.
options Тип кривой анимации, которую вы хотите применить к анимации просмотра.
Наконец, блок кода, где мы устанавливаем рамку кнопки, которую нужно анимировать. Это то же самое, что и предыдущая анимация.
А вот как будет выглядеть анимация с приведенной выше конфигурацией анимации:
UIViewPropertyAnimator
Для немного большего контроля над анимацией пригодится UIViewPropertyAnimator , который предоставляет нам способ приостановить и возобновить анимацию. У вас может быть собственное время, и ваша анимация будет интерактивной и прерываемой. Это очень полезно при выполнении анимаций, которые также взаимодействуют с действиями пользователя.
Классический жест «Слайд для разблокировки» и анимация закрытия/расширения экрана игрока (в приложении «Музыка») являются примерами интерактивных и прерываемых анимаций. Вы можете начать перемещать вид пальцем, затем отпустить его, и вид вернется в исходное положение. Кроме того, вы можете поймать вид во время анимации и продолжить перетаскивать его пальцем.
Ниже приведен простой пример того, как мы можем добиться анимации с помощью UIViewPropertyAnimator :
Мы вызываем API UIViewProperty , передавая продолжительность и кривую анимации.
В отличие от обоих вышеупомянутых API UIView.animate, анимация не запустится, если вы не укажете ее самостоятельно, т.е. вы полностью контролируете весь процесс/поток анимации.
Теперь предположим, что вы хотите еще больше контролировать анимацию. Например, вы хотите спроектировать и контролировать каждый кадр анимации. Для этого есть другой API — animateKeyframes . Но прежде чем мы углубимся в это, давайте быстро рассмотрим, что такое кадр в анимации.
Что такое frame ?
Набор изменений/переходов кадра представления от начального состояния к конечному состоянию определяется как animation , и каждое положение представления во время анимации называется frame .
анимироватьКлючевые кадры
Этот API предоставляет способ разработки анимации таким образом, что вы можете определить несколько анимаций с разными временными интервалами и переходами. После этого API просто интегрирует все анимации в единое целое.
Допустим, мы хотим перемещать нашу кнопку на экране случайным образом. Давайте посмотрим, как мы можем использовать для этого API анимации по ключевым кадрам.
duration Вызовите API, передав продолжительность анимации.
delay Начальная длительность задержки анимации.
options Тип кривой анимации, которую вы хотите применить к анимации просмотра.
animations Блок, который принимает все анимации ключевых кадров, созданные разработчиком/пользователем.
addKeyFrame Вызовите API для разработки каждой анимации. В нашем случае мы определили каждое движение кнопки. У нас может быть столько таких анимаций, сколько нам нужно, добавленных в блок.
relativeStartTime Определяет время начала анимации в коллекции блока анимации.
relativeDuration Определяет общую продолжительность этой конкретной анимации.
center В нашем случае мы просто меняем свойство center кнопки, чтобы кнопка перемещалась по экрану.
А вот так выглядят финальные анимации:
CoreAnimation
Любая анимация на основе UIKit внутренне переводится в основные анимации. Таким образом, инфраструктура Core Animation действует как опорный слой или основа для любой анимации UIKit. Следовательно, все API-интерфейсы анимации UIKit представляют собой не что иное, как инкапсулированные слои основных API-интерфейсов анимации в легко используемой или удобной форме.
API-интерфейсы анимации UIKit не обеспечивают большого контроля над анимацией, которая была выполнена над представлением, поскольку они используются в основном для анимируемых свойств представления. Следовательно, в таких случаях, когда вы намереваетесь контролировать каждый кадр анимации, лучше использовать базовые основные API-интерфейсы анимации напрямую. Кроме того, как анимацию UIView, так и базовую анимацию можно использовать вместе.
UIView + основная анимация
Давайте посмотрим, как мы можем воссоздать ту же самую анимацию смены кнопки вместе с указанием временной кривой с помощью API-интерфейсов UIView и Core Animation.
Мы можем использовать временные функции CATransaction , которые позволяют задавать кривую анимации и управлять ею.
Давайте рассмотрим пример анимации изменения размера кнопки с ее угловым радиусом, используя функцию синхронизации CATransaction и комбинацию анимаций UIView:
curve Представляет временную кривую, которую необходимо применить к анимации.
UIView.animate Наша первая анимация для изменения рамки кнопки.
CABasicAnimation Мы создаем объект CABasicAnimation , ссылаясь на cornerRadius кнопки как на ключевой путь, поскольку это то, что мы хотим анимировать. Точно так же, если вы хотите иметь детальный контроль над анимацией ключевых кадров, вы можете использовать класс CAKeyframeAnimation .
fromValue Представляет начальное значение анимации, т. е. начальное значение cornerRadius кнопки, с которого должна начинаться анимация.
toValue Представляет окончательное значение анимации, т. е. конечное значение cornerRadius кнопки, на которой должна заканчиваться анимация.
cornerRadius Мы должны установить свойство cornerRadius кнопки с окончательным значением анимации, иначе значение angleRadius кнопки автоматически вернется к исходному значению после завершения анимации.
addAnimation Мы присоединяем объект анимации, содержащий конфигурацию всего процесса анимации, к слою, представляя Keypath, для которого необходимо выполнить анимацию.
commit Представляет конец блока кода анимации и запускает анимацию.
Вот как будет выглядеть окончательная анимация:
Этот блог отлично подходит для чтения, чтобы помочь вам создать более сложную анимацию, поскольку он аккуратно проведет вас через большинство API-интерфейсов Core Animation framework с инструкциями, которые помогут вам на каждом этапе пути.
UIKitДинамика
UIKit Dynamics — это физический движок для UIKit, который позволяет добавлять в элементы управления UIKit любые физические поведения, такие как столкновение, гравитация, толчок, щелчок и т. д.
UIKitДинамическийАниматор
Это класс администратора платформы UIKit Dynamics, который регулирует все анимации, запускаемые любым заданным элементом управления пользовательского интерфейса.
UIKitДинамическое поведение
Это позволяет вам добавлять любое физическое поведение к аниматору, который затем позволяет ему работать с прикрепленным к нему видом.
Различные виды поведения для UIKitDynamics включают в себя:
UIAttachmentBehavior
UICollisionBehavior
UIFieldBehavior
UIGravityBehavior
UIPushBehavior
UISnapBehavior
Примерно так выглядит архитектура UIKitDynamics. Обратите внимание, что элементы с 1 по 5 можно заменить одним представлением.
Давайте применим некоторые физические свойства к нашей кнопке. Мы увидим, как применить гравитацию к кнопке, чтобы она давала нам ощущение, что мы имеем дело с реальным объектом.
var dynamicAnimator : UIDynamicAnimator! var gravityBehavior : UIGravityBehavior! dynamicAnimator = UIDynamicAnimator(referenceView: self.view) //1 gravityBehavior = UIGravityBehavior(items: [button]) //2 dynamicAnimator.addBehavior(gravityBehavior) //3
Вот разбивка:
UIKitDynamicAnimator Мы создали объект UIKitDynamicAnimator , который действует как оркестратор для выполнения анимации. Мы также передали супервизор нашей кнопки в качестве эталонного вида.
UIGravityBehavior Мы создали объект UIGravityBehavior и передаем нашу кнопку в элементы массива, на которые внедряется это поведение.
addBehavior Мы добавили объект гравитации в аниматор.
Это должно создать анимацию, как показано ниже: Обратите внимание, как кнопка уходит от центра (исходного положения) экрана вниз и дальше. Мы должны сказать аниматору, чтобы он считал нижнюю часть экрана землей. Вот тут-то и появляется UICollisionBehavior .
UICollisionBehavior Мы создали объект UICollisionBehavior и передали кнопку, чтобы поведение было добавлено к элементу.
translatesReferenceBoundsIntoBoundary Включение этого свойства сообщает аниматору, что он должен использовать границу эталонных представлений как конец, который в нашем случае является нижней частью экрана.
addBehavior Здесь мы добавили в аниматор поведение при столкновении.
Теперь наша кнопка должна коснуться земли и остановиться, как показано ниже: Это довольно аккуратно, не так ли?
Теперь давайте попробуем добавить эффект подпрыгивания, чтобы наш объект казался более реальным. Для этого мы будем использовать класс UIDynamicItemBehavior .
UIDynamicItemBehavior Мы создали объект UIDynamicItemBehavior и передаем кнопку, чтобы поведение было добавлено к элементу.
elasticity Значение должно быть между 0-1, оно представляет эластичность, т.е. количество раз, когда объект должен отскакивать от земли при ударе. Вот где происходит волшебство — настраивая это свойство, вы можете различать разные типы объектов, такие как мячи, бутылки, твердые объекты и так далее.
addBehavior Здесь мы добавили в аниматор поведение при столкновении.
Теперь наша кнопка должна отскакивать, когда она касается земли, как показано ниже:
Этот репозиторий весьма полезен и показывает все поведение UIKitDynamics в действии. Он также предоставляет исходный код для игры с каждым поведением. Это, на мой взгляд, должно служить обширным списком способов выполнения анимации iOS для представлений!
В следующем разделе мы кратко рассмотрим инструменты, которые помогут нам измерить производительность анимации. Я бы также порекомендовал вам рассмотреть способы оптимизации вашей сборки Xcode, поскольку это сэкономит огромное количество времени на разработку.
Настройка производительности
В этом разделе мы рассмотрим способы измерения и настройки производительности анимации iOS. Как разработчик iOS, вы, возможно, уже использовали инструменты Xcode, такие как утечки памяти и выделения памяти, для измерения производительности всего приложения. Точно так же существуют инструменты, которые можно использовать для измерения производительности анимации.
Core Animation
Попробуйте инструмент Core Animation , и вы сможете увидеть FPS, который обеспечивает экран вашего приложения. Это отличный способ измерить производительность/скорость любой анимации, отображаемой в вашем приложении для iOS.
Рисунок
FPS значительно снижается в приложении, которое отображает тяжелый контент, такой как изображения с эффектами, такими как тени. В таких случаях вместо того, чтобы назначать Image непосредственно свойству изображения UIImageView , попробуйте нарисовать изображение отдельно в контексте, используя API-интерфейсы Core Graphics. Это чрезмерно сокращает время отображения изображения, выполняя логику декомпрессии изображения асинхронно, когда она выполняется в отдельном потоке, а не в основном потоке.
Растеризация
Растеризация — это процесс, используемый для кэширования сложной информации о слоях, чтобы эти виды не перерисовывались всякий раз, когда они визуализируются. Перерисовка видов — основная причина снижения FPS, поэтому лучше всего применять растеризацию к видам, которые будут повторно использоваться несколько раз.
Подведение итогов
В заключение я также составил список полезных ресурсов для анимации iOS. Вы можете найти это очень удобным при работе с анимацией iOS. Кроме того, вы также можете найти этот набор инструментов дизайна полезным в качестве шага (дизайна) перед тем, как углубиться в анимацию.
Я надеюсь, что смог охватить как можно больше тем, связанных с анимацией iOS. Если есть что-то, что я, возможно, пропустил в этой статье, сообщите мне об этом в разделе комментариев ниже, и я был бы рад внести дополнение!