Skip to content

Instantly share code, notes, and snippets.

@MarcAlx
Last active June 28, 2022 09:36
Show Gist options
  • Save MarcAlx/2b8769659d2c4048e1eeb95157754e0f to your computer and use it in GitHub Desktop.
Save MarcAlx/2b8769659d2c4048e1eeb95157754e0f to your computer and use it in GitHub Desktop.
Apple music animated bars - SwiftUI - Swift Playground
import SwiftUI
import PlaygroundSupport
struct ContentView: View {
var body: some View {
Bars()
}
}
struct Bars:View {
var body: some View {
HStack(alignment: .bottom) {
ForEach((1...10), id: \.self) { value in
Bar().foregroundColor(.blue)
}
}
}
}
struct Bar:View {
@State var size: CGFloat = CGFloat(Float.random(in: 0..<1))
@State var nexSize:CGFloat = CGFloat(Float.random(in: 0..<1))
//animation duration in second
let animationDuration:Double = 1
var animation:Animation {
Animation.linear(duration: self.animationDuration)
}
//update size and update nextsize, which will trigger next animation
func updateSizeAndTriggerNextAnimation(newSize:CGFloat){
self.size = newSize
//as there's no completion handler on animation, update nextsize just before current animation end
DispatchQueue.main.asyncAfter(deadline: .now() + self.animationDuration * 0.8) {
self.nexSize = CGFloat(Float.random(in: 0..<1))
}
}
var body: some View {
HStack(alignment: .bottom){
RoundedRectangle(cornerRadius: 25)
.scaleEffect(y:size,anchor: .bottomLeading)
//On appear trigger animation
.onAppear() {
withAnimation(self.animation) {
self.updateSizeAndTriggerNextAnimation(newSize: self.nexSize)
}
}
//when nextSize change launch new animation
.onChange(of: nexSize) { [size] newState in
withAnimation(self.animation) {
self.updateSizeAndTriggerNextAnimation(newSize: self.nexSize)
}
}
}
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.setLiveView(ContentView())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment