Skip to content

Instantly share code, notes, and snippets.

@gustafnilklint
Created December 11, 2020 09:00
Show Gist options
  • Save gustafnilklint/7655b397c17adb653ee4565d8817d529 to your computer and use it in GitHub Desktop.
Save gustafnilklint/7655b397c17adb653ee4565d8817d529 to your computer and use it in GitHub Desktop.
A simple progress indicator Written in swiftUI
//
// Spinner.swift
// IHS-aafh
//
// Created by Gustaf Nilklint on 2020-05-28.
// Copyright © 2020 Gustaf Nilklint. All rights reserved.
//
import SwiftUI
struct Spinner: View {
var color : Color
@State private var fillPoint = 0.0
@State private var colorIdx = 0
@State private var rotation = 0.0
private let duration = 1.2
private var pathAnimation : Animation {
Animation.easeOut(duration: duration).repeatForever(autoreverses: false)
}
private var rotationAnimation: Animation {
Animation.linear(duration: 4.0)
.repeatForever(autoreverses: false)
}
var body: some View {
GeometryReader{ geo in
Ring(fillPortion: self.fillPoint)
.stroke(self.color.opacity(0.7), style: StrokeStyle(lineWidth: geo.size.width/12, lineCap: .round))
.rotationEffect(.degrees(self.rotation))
.onAppear() {
withAnimation(self.pathAnimation) {
self.fillPoint = 1.0
}
withAnimation(self.rotationAnimation, {
self.rotation = 360
})
}
}
}
}
struct Ring : Shape {
var fillPortion : Double
var delayedPoint : Double = 0.55
var animatableData: Double {
get { return fillPortion }
set{ fillPortion = newValue }
}
func path(in rect: CGRect) -> Path {
var start : Double
let end = (360 * fillPortion)
if fillPortion > delayedPoint {
start = (2 * fillPortion * 360)
}else{
start = 0
}
var path = Path()
path.addArc(center: CGPoint(x: rect.midX, y: rect.midY),
radius: rect.width/2,
startAngle: .degrees(start),
endAngle: .degrees(end),
clockwise: false)
return path
}
}
struct SpinnerSampleView : View {
@State var loading = false
var body: some View {
VStack {
Button("Load", action: {
withAnimation{
loading.toggle()
}
})
HStack {
Text("Loading")
Spinner(color: .gray).frame(width: 50, height: 50)
}.opacity(loading ? 1 : 0 )
Spinner(color: .green).frame(width: 50, height: 50).opacity(loading ? 1 : 0 )
if loading {
Spinner(color: .blue).frame(width: 50, height: 50)
}
Spinner(color: .red).frame(width: 50, height: 50).opacity(loading ? 1 : 0 )
}
}
}
struct Spinner_Previews: PreviewProvider {
static var previews: some View {
SpinnerSampleView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment