В SwiftUI анимации создаются путем изменения значений свойств с течением времени, а инфраструктура заботится о плавной интерполяции значений свойств для создания визуально привлекательного перехода. SwiftUI использует декларативный синтаксис для описания анимаций, упрощая создание сложных анимаций, которые реагируют на действия пользователя и другие события.
Анимации в SwiftUI создаются с помощью замыкания withAnimation
, которому передается блок кода, изменяющий состояние представления. SwiftUI автоматически анимирует изменения состояния, происходящие в замыкании withAnimation
, интерполируя значения свойств от их начальных значений до их конечных значений в течение заданного времени. Платформа также предоставляет ряд встроенных анимаций, таких как базовые преобразования (масштабирование, поворот и т. д.), затухание и многое другое, которые можно легко добавить в представления.
struct AnimatedCircle: View { @State private var scale: CGFloat = 1.0 var body: some View { Circle() .fill(Color.red) .frame(width: 100, height: 100) .scaleEffect(scale) .onTapGesture { withAnimation { self.scale += 0.1 } } } }
В этом примере структура AnimatedCircle
определяет представление Circle
с модификатором scaleEffect
, который изменяет размер круга. При касании круга свойство состояния scale
увеличивается на 0.1
, а замыкание withAnimation
используется для анимации изменения. Анимация будет интерполировать переход от исходного размера круга к его новому размеру в течение продолжительности по умолчанию 0.25
секунд. Вы можете настроить продолжительность анимации, временную кривую и другие параметры, передав аргументы замыканию withAnimation
.
SwiftUI также предоставляет возможность создавать собственные анимации с использованием протокола Animatable
. Этот протокол позволяет вам определять настраиваемые анимируемые свойства и то, как они должны интерполироваться во время анимации. Например, вы можете определить пользовательское анимируемое свойство для цвета и указать способ перехода цвета от одного значения к другому во время анимации. например:
struct AnimatedRectangle: View { @State private var animatableValue: Double = 0 var body: some View { Rectangle() .fill(Color.blue) .frame(width: 200, height: 100) .cornerRadius(CGFloat(animatableValue)) .onTapGesture { withAnimation(.interactiveSpring()) { self.animatableValue = 20 } } } }
В этом примере у нас есть представление Rectangle
с модификатором cornerRadius
, который принимает значение CGFloat
. Свойство состояния animatableValue
объявлено как Double
, но оно преобразуется в CGFloat
при передаче модификатору cornerRadius
. При касании прямоугольника animatableValue
устанавливается на 20
внутри замыкания withAnimation
, что запускает анимацию для интерполяции изменения исходного значения на новое значение. Используется анимация .interactiveSpring()
, которая создает пружинящую анимацию, реагирующую на скорость жеста.
Чтобы сделать тип Double
анимируемым, мы можем соответствовать протоколу Animatable
и предоставить метод .animation
:
extension Double: Animatable { public var animatableData: Double { get { self } set { self = newValue } } public typealias AnimatableData = Double }
Благодаря этой реализации тип Double
теперь можно использовать в качестве анимируемого свойства в анимациях SwiftUI.
Как всегда, весь код можно скачать с моей страницы на github.