0Pricing
Swift Academy · Урок

Пользовательские AnimatableModifier и Animatable

Анимируйте собственноручно отрисованный контент, реализуя Animatable и AnimatableModifier.

«Пользовательские AnimatableModifier и Animatable» — бесплатный урок Swift Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.

Протокол Animatable

Animatable сообщает SwiftUI, как интерполировать тип во время анимации. Фигуры автоматически соответствуют этому протоколу.

struct Wave: Shape, Animatable {
  var amplitude: Double
  var animatableData: Double {
    get { amplitude }
    set { amplitude = newValue }
  }
  func path(in rect: CGRect) -> Path { Path() }
}

Свойство animatableData

SwiftUI считывает и записывает animatableData на каждом кадре анимации, чтобы интерполировать значения от начального до конечного.

struct GrowingCircle: Shape {
  var radius: Double
  var animatableData: Double {
    get { radius }
    set { radius = newValue }
  }
  func path(in rect: CGRect) -> Path {
    Path(ellipseIn: CGRect(x: rect.midX-radius, y: rect.midY-radius, width: radius*2, height: radius*2))
  }
}

AnimatablePair для нескольких значений

Используйте AnimatablePair, чтобы одновременно анимировать два независимых значения.

struct Sector: Shape {
  var startAngle: Double, endAngle: Double
  var animatableData: AnimatablePair<Double, Double> {
    get { AnimatablePair(startAngle, endAngle) }
    set { startAngle = newValue.first; endAngle = newValue.second }
  }
  func path(in rect: CGRect) -> Path { Path() }
}

ViewModifier и Animatable

Соответствие ViewModifier протоколу Animatable позволяет анимировать произвольные визуальные эффекты.

struct Shake: ViewModifier, Animatable {
  var animatableData: Double = 0
  func body(content: Content) -> some View {
    content.offset(x: sin(animatableData * .pi * 4) * 8)
  }
}

Управление анимацией

Измените анимируемое значение внутри withAnimation, и SwiftUI выполнит интерполяцию через animatableData.

struct ShakeView: View {
  @State private var shakes = 0.0
  var body: some View {
    Text("Hello")
      .modifier(Shake(animatableData: shakes))
      .onTapGesture {
        withAnimation(.linear(duration: 0.5)) { shakes += 1 }
      }
  }
}

AnimatableModifier (устарел) и Animatable с ViewModifier

AnimatableModifier устарел в более поздних версиях SDK. Предпочтительно напрямую объявлять соответствие вашего ViewModifier протоколу Animatable.

// Modern approach:
struct MyMod: ViewModifier, Animatable { ... }
// Avoid (deprecated):
// struct MyMod: AnimatableModifier { ... }

Пользовательские числовые типы в качестве animatableData

Любой тип, соответствующий VectorArithmetic, может использоваться как animatableData. Этому требованию соответствуют CGFloat, Double и AnimatablePair в Swift.

extension MyColor: VectorArithmetic {
  static func += (lhs: inout MyColor, rhs: MyColor) { ... }
  mutating func scale(by rhs: Double) { ... }
  var magnitudeSquared: Double { ... }
}

Модификатор на основе прогресса

Распространённый шаблон: анимировать значение progress от 0 до 1 и вычислять визуальные свойства внутри модификатора.

struct FillModifier: ViewModifier, Animatable {
  var progress: Double
  var animatableData: Double { get { progress } set { progress = newValue } }
  func body(content: Content) -> some View {
    content.overlay(Color.blue.opacity(progress))
  }
}

Цепочка с .animation

Добавьте анимацию, чтобы автоматически изменять значение прогресса анимируемого модификатора при изменении состояния.

Text("Loading")
  .modifier(FillModifier(progress: isLoaded ? 1 : 0))
  .animation(.easeInOut(duration: 1.0), value: isLoaded)

Анимация пользовательских фигур

Самое мощное применение — морфинг между двумя фигурами пути с интерполяцией управляющих точек через animatableData.

struct Blob: Shape, Animatable {
  var bulge: Double
  var animatableData: Double { get { bulge } set { bulge = newValue } }
  func path(in rect: CGRect) -> Path {
    // compute bezier with bulge-adjusted control points
    Path()
  }
}

Производительность

SwiftUI вызывает тело модификатора на каждом кадре анимации. Сведите вычисления внутри body к минимуму, чтобы обеспечить плавную частоту 60 или 120 кадров в секунду.

// OK: simple math in body
// AVOID: network calls, heavy computation in animated body

Проверка знаний

Что SwiftUI считывает и записывает на каждом кадре анимации для интерполяции пользовательского анимируемого типа?

Итоги урока

Обеспечьте соответствие фигур или модификаторов представлений протоколу Animatable и предоставьте animatableData (значение типа VectorArithmetic). SwiftUI интерполирует его на каждом кадре. Для двух значений используйте AnimatablePair. Запускайте анимацию с помощью withAnimation или .animation.

Часто задаваемые вопросы

Урок «Пользовательские AnimatableModifier и Animatable» бесплатный?

Да — полный текст урока «Пользовательские AnimatableModifier и Animatable» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.

Чему я научусь в уроке «Пользовательские AnimatableModifier и Animatable»?

Анимируйте собственноручно отрисованный контент, реализуя Animatable и AnimatableModifier. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Swift Academy?

Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Пользовательские AnimatableModifier и Animatable»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Swift Academy?

Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Неявные и явные анимации
  2. matchedGeometryEffect для эффектных переходов
  3. Пользовательские AnimatableModifier и Animatable
  4. TimelineView и Canvas для высокопроизводительной отрисовки
← Назад к Swift Academy