В этой статье мы рассмотрим, как использовать SF-символы для легкого создания потрясающих анимаций загрузки.
SF-символы
SF-символы значительно развились с момента своего появления и теперь способны применять мощные стилистические и value эффекты ко многим встроенным символам.
Это делает их отличной альтернативой многим вещам, которые раньше требовали написания собственного кода. Давайте посмотрим, как можно использовать их для создания анимации загрузки.
Старая анимация точек загрузки
В моём проекте с открытым исходным кодом SwiftUIKit есть следующий код для создания анимированных точек загрузки:
public struct DotLoadingAnimation: View {
public init(
dotCount: Int = 3,
interval: Double = 0.25
) {
self.dotCount = dotCount
self.timer = Timer.publish(every: interval, on: .main, in: .common)
.autoconnect()
}
private let dotCount: Int
private let timer: Publishers.Autoconnect<Timer.TimerPublisher>
@State
private var currentDotCount = 0
public var body: some View {
Text(dotText)
.onReceive(timer) { _ in increaseDotCount() }
}
}
private extension DotLoadingAnimation {
var dotText: String {
if currentDotCount == 0 { return "" }
return (0..<currentDotCount)
.map { _ in "." }
.joined(separator: "")
}
}
private extension DotLoadingAnimation {
func increaseDotCount() {
var newCount = currentDotCount + 1
if newCount > dotCount {
newCount = 0
}
currentDotCount = newCount
}
}
У него так же был DotLoadingAnimationText, который мог добавлять анимацию загрузки к любому текстовому представлению:
public struct DotLoadingAnimationText: View {
public init(
text: LocalizedStringKey,
bundle: Bundle? = nil,
dotCount: Int = 3,
interval: Double = 0.8
) {
self.text = text
self.bundle = bundle
self.dotCount = dotCount
self.interval = interval
}
private let text: LocalizedStringKey
private let bundle: Bundle?
private let dotCount: Int
private let interval: Double
public var body: some View {
HStack(spacing: 0) {
Text(text, bundle: bundle)
Text(staticDotString)
}
.opacity(0)
.overlay(titleAnimation, alignment: .leading)
}
}
private extension DotLoadingAnimationText {
var dotAnimation: some View {
DotLoadingAnimation(
dotCount: dotCount,
interval: interval
)
}
var staticDotString: String {
(0..<dotCount)
.map { _ in "." }
.joined(separator: "")
}
var titleAnimation: some View {
HStack(spacing: 0) {
Text(text)
dotAnimation
}
}
}
Это довольно большой код для объекта, который просто отображает набор точек. Поскольку это обычный текст, его можно стилизовать стандартными модификаторами SwiftUI:
DotLoadingAnimation(dotCount: 10)
.foregroundStyle(.blue)
.font(.largeTitle.bold())
Это создает настраиваемую точечную анимацию, где точки могут отображаться вместе с другим текстом:
Это просто в использовании, но весь этот код для такого простого представления больше не нужен. Давайте посмотрим, как можно использовать SF-символы для создания аналогичного эффекта с меньшим объёмом кода и большей гибкостью.
Анимация загрузки на основе SF-символов
Если мы ориентируемся на iOS 17+, мы можем использовать SF-символы для создания красивой анимации загрузки с минимальным объёмом кода:
Image(systemName: "ellipsis")
.foregroundStyle(.blue)
.font(.largeTitle.bold())
.symbolEffect(.variableColor)
Это создает плавную, постоянно повторяющуюся точечную анимацию, которую можно стилизовать с помощью шрифтов, цветов текста и т. д.:
Вы можете добавлять модификаторы к .variableColor для настройки анимации. Например, .hideInactiveLayers скрывает неактивные точки, .iterative выделяет только текущую точку и т.д.
Эти модификаторы можно комбинировать для создания сложных комбинированных эффектов. Например, так:
Image(systemName: "ellipsis")
.foregroundStyle(.blue)
.font(.largeTitle.bold())
.symbolEffect(
.variableColor
.iterative
.hideInactiveLayers
)
Этот код реализует эффект переменного цвета, который последовательно скрывает неактивные слои. В результате получится кастомный эффект:
Эти возможности композиции позволяют легко создавать потрясающие пользовательские эффекты практически без написания кода.
И самое приятное, что это работает для всех символов, поддерживающих переменные цвета, например, для символа Wi-Fi:
Если вы ориентируетесь на iOS 18+ и совместимые версии, вы получите доступ к ещё большему количеству эффектов, например, .bounce. Каждый эффект имеет собственный набор модификаторов, что позволяет настраивать их для достижения максимального результата.
Заключение
SF Symbols позволяет легко создавать мощные и гибкие анимации и эффекты. Если вы ориентируетесь на последние версии ОС, я бы даже назвал их предпочтительным выбором по сравнению с написанием кучи кастомного кода.
Поскольку SF-символы настолько хороши, я решил отказаться от старой анимации загрузки точек в SwiftUIKit.

