Loading Indicators
Last updated
Was this helpful?
Last updated
Was this helpful?
⟩ ⟩ ⟩ loading indicators
struct ContentView: View {
@State private var isComplete = false
var body: some View {
VStack {
HStack {
TapView() // ⭐️ tap to animate
CircularLoadingView() // ⭐️ circular loading indicator
}
.frame(height: 100)
LinearLoadingView() // ⭐️ linear loading indicator
.padding(.top, 40)
}
.padding()
}
}
struct TapView: View {
// ⭐️ 1. animation states (true/false)
@State private var isComplete = false
var body: some View {
ZStack {
Circle()
.fill(Color(.systemGray6))
Circle()
// ⭐️ 2. things to animate (shape path parameter)
.trim(from: 0, to: isComplete ? 1 : 0.1)
.stroke(Color.green, lineWidth: 14)
.rotationEffect(.degrees(-90))
Text("Tap")
.foregroundColor(.secondary)
}
// ⭐️ 4. event to trigger animation (tap)
.onTapGesture {
// ⭐️ 3. animation curve (.default)
withAnimation { isComplete.toggle() }
}
}
}
struct CircularLoadingView: View {
// ⭐️ 1. animation states (true/false)
@State private var isLoading = false
var body: some View {
VStack {
ZStack {
Circle()
.stroke(.orange, lineWidth: 14)
Circle()
.trim(from: 0, to: 0.7)
.stroke(.pink, lineWidth: 10)
.frame(width: 100, height: 100)
// ⭐️ 2. things to animate (rotation angle)
.rotationEffect(.degrees(isLoading ? 360 : 0))
// ⭐️ 3. animation curve (.linear)
.animation(.linear(duration: 2).repeatForever(autoreverses: false))
// ⭐️ 4. event to trigger animation (on appear)
.onAppear {
self.isLoading = true
}
Text("Loading")
.foregroundColor(.secondary)
}
}
}
}
struct LinearLoadingView: View {
// ⭐️ 1. animation states (true/false)
@State private var isLoading = false
var body: some View {
VStack {
Text("Loading")
.foregroundColor(.secondary)
ZStack {
Capsule()
.fill(Color(.systemGray5))
.frame(width: 250, height: 8)
Capsule()
.fill(.blue)
.frame(width: 30, height: 6)
// ⭐️ 2. things to animate (offset)
.offset(x: isLoading ? 110 : -110)
// ⭐️ 3. animation curve (.linear)
.animation(.linear(duration: 1).repeatForever())
// ⭐️ 4. event to trigger animation (on appear)
.onAppear {
self.isLoading = true
}
}
}
}
}
⬆️ 需要: view + .frame(), floating +−⨉÷ int
👥 相關: delay
struct DotsLoadingIndicator: View {
// ⭐️ 1. animation states (true/false)
@State private var isLoading = false
var body: some View {
HStack {
ForEach(0..<5) { i in
Circle()
.frame(8) // 🌀 View+
.foregroundColor(.green)
// ⭐️ 2. things to animate (scale)
.scaleEffect(isLoading ? 0.2 : 1)
// ⭐️ 3. animation curve (.linear)
.animation(
.linear(duration: 0.8)
.repeatForever()
// ⭐️ delay
.delay(0.2 * i) // 🌀 FloatingPoint+
)
}
}
// ⭐️ 4. event to trigger animation (on appear)
.onAppear { isLoading = true }
}
}
compare: TimerView (scheduledTimer) - progress indicator.
, Ch. 9: Animations & Transitions ⟩