โจLoading Indicators
Last updated
Last updated
SwiftUI โฉ Animations โฉ examples โฉ 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
}
}
}
}
}
โฌ๏ธ ้่ฆ๏ผ .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.