- PVSM.RU - https://www.pvsm.ru -
Не так давно на WWDC 2016 был анонсирован обновленный интерфейс работы с интерактивными анимациями в iOS 10: теперь у разработчиков появился гибкий инструмент их создания, управления и модификации. В этой статье речь пойдет о том, какие произошли изменения и что из себя представляет новое API.
Центральным классом нового API является UIViewPropertyAnimator, предоставляющий свой функционал на основе двух протоколов UIViewAnimating и UIViewImplicitlyAnimating, которые будут рассмотрены ниже.
С помощью данного класса можно:
Пример использования:
// Скорость анимации
let parameters = UICubicTimingParameters(animationCurve: .easeIn)
// Конфигурирование аниматора с учетом длительности и скорости
let animator = UIViewPropertyAnimator(duration: 5.0, timingParameters: parameters)
// Набор анимаций (как во всем знакомом UIView.animate(withDuration:, animations:))
animator.addAnimations {
view.center = CGPoint(x: 150, y: 200)
view.transform = CGAffineTransform(rotationAngle: CGFloat(M_PI_2))
view.backgroundColor = UIColor.red()
}
// Completion block
animator.addCompletion { _ in
view.backgroundColor = UIColor.orange()
}
// Запуск проигрывания анимации
animator.startAnimation()
Может показаться, что такая реализация более многословна по сравнению со старым API, зато теперь есть аниматор, который можно реиспользовать/изменять/сохранять и наслаждаться остальными преимуществами наличия цельного объекта.
Также Apple предоставляет новые протоколы:
Этот протокол отвечает за основные действия, которые мы можем выполнить с аниматором: запуск, пауза, остановка, перемотка, получение текущего состояния и позиции анимации. Больше информации можно получить в документации [1]. Остановимся на паре методов и свойств чуть подробнее:
var fractionComplete: CGFloat { get set }
animator.fractionComplete = fraction
С помощью такого свойства можно поэтапно продвигаться по анимации вперед/назад, получая ее состояние в выбранный момент времени. Благодаря такой возможности пользователь может взаимодействовать с интерфейсом как с чем-то живым и интерактивным.
Сначала тянем иконку вправо и вручную проматываем анимацию (UIPanGestureRecognizer). Затем тапаем по иконке и смотрим на анимацию, которая проигрывается сама (UITapGestureRecognizer).
func finishAnimation(at: UIViewAnimatingPosition)
Входной параметр at показывает, в какой позиции полностью завершится анимация.
Варианты значений enum UIViewAnimatingPosition:
Параметр позиции может оказаться очень полезным, когда потребуется закончить анимацию в нестандартном состоянии. Например, в середине цикла или на последнем кадре.
func stopAnimation(_ withoutFinishing: Bool)
Параметр withoutFinishing позволяет либо остановить анимацию полностью (как при использовании finishAnimation), либо перевести в состояние stopped, из которого анимацию можно продолжить с текущего места.
Наглядное изображение изменения состояния:
И еще несколько интересных свойств UIViewAnimating:
// Можно ли анимацию ставить на паузу или останавливать
var isInterruptible: Bool
// Способ обработки тачей (по умолчанию false)
var isManualHitTestingEnabled: Bool
При значении по умолчанию анимируемый объект будет получать все касания пользователя.
Если выставить isManualHitTestingEnabled = true, то все тачи будет получать не объект в своем текущем состоянии (presentation layer), а его модельный слой (model layer), то есть в финальном состоянии, как будто анимация уже кончилась.
Этот протокол наследуется от предыдущего (UIViewAnimating) и предоставляет важную часть функционала: добавление анимаций через блок и создание completion block.
Одна из новых возможностей — это продолжение анимации после паузы или остановки, причем с изменением timing function.
let newParameters = UICubicTimingParameters(animationCurve: .easeOut)
animator.continueAnimation(withTimingParameters: newParameters, durationFactor: 2.0)
Это может пригодиться, если нужно изменить темп анимации после взаимодействия с пользователем (остановки или паузы анимации).
Используется при создании объекта UIViewPropertyAnimator для установки timing function через UISpringTimingParameters или UICubicTimingParameters.
Сейчас UIKIt дает нам только четыре старые добрые функции скорости (easeInOut, easeIn, easeOut, linear).
Но в новом API появился простор для фантазии дизайнеров — возможность создавать свои timing functions по двум контрольным точкам:
let controlPoint1 = CGPoint(x: 0.2, y: 0.1)
let controlPoint2 = CGPoint(x: 0.8, y: 0.8)
let parameters = UICubicTimingParameters(controlPoint1: controlPoint1, controlPoint2: controlPoint2)
animator = UIViewPropertyAnimator(duration: 0.5, timingParameters: parameters)
Здесь интересным моментом является то, что скорость теперь вектор, а не скаляр. Раньше скорость была направлена вдоль линии в отличие от нового API, где расчет идет по двум осям, а значит, анимация выглядит более натурально.
А еще Apple открыли для использования spring equation, то есть теперь можно устанавливать любые коэффициенты и настройки для UISpringTimingParameters, но надо учитывать, что в этом случае длительность игнорируется и высчитывается соответственно параметрам:
// Spring equation
init(mass: CGFloat, stiffness: CGFloat, damping: CGFloat, initialVelocity velocity: CGVector)
После просмотра лекции и нескольких примеров кода остается общее впечатление, что добавилось разнообразие и возможности для экспериментов с timing functions и модификацией анимаций, а API стало более многословным, но гибким. Будем надеяться, разработчикам теперь станет еще проще и приятнее добавлять интерактив в свои приложения!
Подробнее познакомиться с примерами можно в лекции Advances in UIKit Animations and Transitions [2].
Автор: REDMADROBOT
Источник [3]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/ios-development/165356
Ссылки в тексте:
[1] документации: https://developer.apple.com/reference/uikit/uiviewanimating
[2] Advances in UIKit Animations and Transitions: https://developer.apple.com/videos/play/wwdc2016/216/
[3] Источник: https://habrahabr.ru/post/305596/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.