Skip to content

Instantly share code, notes, and snippets.

@pennisi
Created December 8, 2020 15:29
Show Gist options
  • Save pennisi/11efb96e7cea3e382eaa9e787d74c56a to your computer and use it in GitHub Desktop.
Save pennisi/11efb96e7cea3e382eaa9e787d74c56a to your computer and use it in GitHub Desktop.
SwiftUI success animation/HUD
//To configure the contents of the HUD
struct HUDConfig {
var text: String
var icon: Image
var autohide = true
static func success(_ s: String) -> HUDConfig {
return HUDConfig(text: s, icon: Image(systemName: "checkmark.circle.fill"))
}
}
//Basically works like this:
//At first only icon is shown and with animation of 'appear' it pops up (scales from 0 to 1)
//Then after some delay the 'morph' flag gets set too.
//This means, the text appears,
//the icon gets scaled down to 0.4
//its opacity animates to 0
//it rotates
//and moves to the right :) all together
struct HUDView: View {
@State var morph = false
@State var appear = false
var config: HUDConfig
var body: some View {
Group {
ZStack {
if morph {
Text(config.text)
.font(.headline)
.foregroundColor(Color.white)
.padding()
.transition(.opacity)
}
config.icon
.foregroundColor(Color.white)
.font(Font.system(size: 24))
.padding()
.rotationEffect(.degrees(!morph ? 0 : 360))
.offset(x: !morph ? 0 : 90, y: 0)
.opacity(!morph ? 1 : 0)
.scaleEffect(!morph ? 1 : 0.4)
}
}
.background(Color.black.opacity(0.7))
.continuous(radius: 15)
.scaleEffect(appear ? 1 : 0.0001)
.onAppear {
//transition, icon plops in
withAnimation(Animation.spring()) {
appear = true
}
//after some delay text appears and icon rolling disappears
DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) {
withAnimation(Animation.spring().speed(0.7)) {
morph = true
}
}
}
}
}
@ArnavMotwani
Copy link

Looks good, can you share an example implementation, how can I use this in an app?

@ArnavMotwani
Copy link

ArnavMotwani commented Dec 9, 2020

Here is my revision, it has a couple changes

//To configure the contents of the HUD
struct HUDConfig {
    var text: String
    var icon: Image
    var autohide = true
    
    static func success(_ s: String) -> HUDConfig {
        return HUDConfig(text: s, icon: Image(systemName: "checkmark.circle.fill"))
    }
}

//Basically works like this:
//At first only icon is shown and with animation of 'appear' it pops up (scales from 0 to 1)
//Then after some delay the 'morph' flag gets set too.
//This means, the text appears,
//its opacity animates to 0
//and moves to the right :) all together
struct HUDView: View {
    @State var morph = false
    @State var appear = false
    var config: HUDConfig
    
    var body: some View {
        Group {
                ZStack {
                    if morph {
                        Text(config.text)
                            .font(.headline)
                            .foregroundColor(Color.white)
                            .padding()
                            .transition(.opacity)
                    }
                    
                    config.icon
                        .foregroundColor(Color.white)
                        .font(.title)
                        .padding()
                        .offset(x: !morph ? 0 : 90, y: 0)
                        .opacity(!morph ? 1 : 0)
                }
        }
        .background(RoundedRectangle(cornerRadius: 10).foregroundColor(Color.black.opacity(0.7)))
        .scaleEffect(appear ? 1 : 0.0001)
        .onAppear {
           //transition, icon plops in
            withAnimation(Animation.spring()) {
                appear = true
            }
            //after some delay text appears and icon rolling disappears
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.7) {
                withAnimation(Animation.easeInOut.speed(0.7)) {
                    morph = true
                }
            }
        }
    }
    
}

@simoalx
Copy link

simoalx commented Feb 14, 2021

Any particular reason you put the ZStack in a Group?

@pennisi
Copy link
Author

pennisi commented Feb 14, 2021

Hm good point. I think it’s unnecessary. Can’t remember why I put it there put should work without it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment