TimelineView — это мощное контейнерное представление в SwiftUI, предназначенное для создания динамических интерфейсов, изменяющихся во времени. В отличие от традиционных представлений, которые обновляются только при изменении состояния, TimelineView позволяет обновлять информацию по определенному расписанию, что делает его идеальным для плавной, непрерывной анимации и создания интерактивных элементов, реагирующих на течение времени.
TimelineView сам по себе не имеет визуального вида, он просто управляет обновлениями своего содержимого в зависимости от времени.
struct ContentView: View {
var body: some View {
TimelineView(.periodic(from: .now, by: 1)) { context in
Text(context.date, format: .dateTime.second())
}
}
}
Для указания времени обновления TimelineView требуется свойство, соответствующее протоколу TimelineSchedule. Существует несколько альтернатив, которые дают нам больше контроля над созданием последовательности времен:
animation: позволяет создать расписание с паузами, которые обновляются с определенной частотойeveryMinute: обновляет представление временной шкалы в начале каждой минутыexplicit: обновляет представление в определенные моменты времени с помощью массиваDateperiodic: обновляет представление через регулярные промежутки времени
Кроме того, замыкание TimelineView предоставляет доступ к свойству типа TimelineView.Context, которое можно использовать для настройки внешнего вида содержимого. Объект TimelineView.Context имеет два свойства:
date, которая вызвала обновление. В примере выше представление отправляет эту дату в аналоговый таймер, который вы создаете, чтобы представление таймера знало, как рисовать стрелки.cadence, частота, с которой вы обновляете представление. Например, с помощью каденции можно решить, когда уместно обновлять таймер.
Давайте посмотрим, как можно использовать контейнер TimelineView в представлении SwiftUI для создания простой анимации, которая будет генерировать случайный цвет и изменять масштаб изображения:
import SwiftUI
struct PulsatingCircleView: View {
var body: some View {
TimelineView(.animation(minimumInterval: 0.5)) { timeline in
let timeInterval = timeline.date.timeIntervalSinceReferenceDate
// Color animation based on sine wave
let hue = (sin(timeInterval) + 1) / 2
let animatedColor = Color(hue: hue, saturation: 1.0, brightness: 1.0)
// Size animation based on sine wave - pulsating effect
let baseScale = 1.0
let scaleVariation = 0.5
let imageScale = baseScale + scaleVariation * sin(timeInterval * 2.5)
Image(.image)
.overlay {
Circle()
.fill(animatedColor)
.blendMode(.color)
}
.scaleEffect(imageScale)
.animation(.easeInOut, value: imageScale)
}
}
}
struct ContentView: View {
var body: some View {
VStack {
PulsatingCircleView()
}
}
}
#Preview {
ContentView()
}
Представленный пример иллюстрирует, как анимировать изображение с кругом, который постепенно меняет цвет и размер с течением времени. Это достигается путем периодического обновления представления с помощью TimelineView. Переход цвета осуществляется с помощью синусоиды, а размер круга изменяется для создания пульсирующего эффекта. Этот пульсирующий эффект накладывается на изображение с помощью режима наложения.

