Animation of Shazam's button in SwiftUI

436 Views Asked by At

I would like to make an animation like Shazam's Button but I can't manage to do it...

Anyone have an idea how to make this animation in SwiftUI?

Here is the code :

import SwiftUI
import Foundation

struct SpeechButton: View {
    
    @State var isPressed:Bool = false

    var body: some View {
        
        Button(action:{
            
        }){
            ZStack {
                
    //-->       // if self.isPressed { RoundAnimation() }
                
                Image(systemName: "waveform")// Button Image
                    .resizable()
                    .frame(width: 40, height: 40)
                    .foregroundColor(.white)
                    
            }
        )
    }
}

Thanks in advance for your help people :)

1

There are 1 best solutions below

0
ios coder On BEST ANSWER

After your code update even has more issue with it, it was not runnable, how ever you just gave me an Empty Button to work on it!

Here I got some thing for you:

    import SwiftUI


struct ContentView: View {
    
    @State var startAnimation: Bool = false
    @State var random: CGFloat = 0
    
    var timer = Timer.publish (every: 0.1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        


        Button(action: {
            
            // your logic!
            
        }){

            ZStack
            {
                Circle()
                    .fill(Color(UIColor.systemTeal))
 
                
                Image(systemName: "waveform")
                    .resizable()
                    .frame(width: 100, height: 100)
                
                
            }
            .frame(width: 200, height: 200)
            .scaleEffect(startAnimation ? CGFloat(1*random) : 1 )
            .animation(.easeInOut)
            .onTapGesture {
                startAnimation.toggle()

                if startAnimation == false
                {
                    timer.upstream.connect().cancel()

                }
  
            }
    
            
        }
        .onReceive(timer) { _ in
            
            random = CGFloat.random(in: 0.5...1)
            
        }

        
        
        
    }
    
}

Update Code: Version 2.0.0

import SwiftUI


struct ContentView: View {
    
    @State var startAnimation: Bool = false
    @State var random: CGFloat = 0
    

    @State var timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
    
    
    func stopTimer() {
        timer.upstream.connect().cancel()
    }
    
    func startTimer() {
        timer = Timer.publish(every: 0.1, on: .main, in: .common).autoconnect()
    }
    
    
    
    var body: some View {
        


        Button(action: {
            
            // your logic!
            
        }){

            ZStack
            {
                Circle()
                    .fill(RadialGradient(gradient: Gradient(colors: [Color(UIColor.systemTeal), Color.white.opacity(0.1)]), center: .center, startRadius: 0, endRadius: 180))
 
                
                Image(systemName: "waveform")
                    .resizable()
                    .frame(width: 100, height: 100)
                
                
            }
            .frame(width: 200, height: 200)
            .scaleEffect(startAnimation ? random : 1 )
            .animation(.easeInOut)
            .onTapGesture {
                startAnimation.toggle()

                if startAnimation == false
                {
                    stopTimer()

                }
                else
                {
                    startTimer()
                }
  
            }
    
            
        }
        .onReceive(timer) { _ in
            random = CGFloat.random(in: 0.5...1)
        }
        .onAppear()
        {
            stopTimer()
        }

        
        
        
    }
    
}

Update Code: Version 3.0.0 Much more and better Animation

    import SwiftUI


struct ContentView: View {
    
    @State var startAnimation: Bool = false
    @State var random1: CGFloat = 0.5
    @State var random2: CGFloat = 0.5
    
    
    @State var timer = Timer.publish(every: 0.3, on: .main, in: .common).autoconnect()
    
    
    func stopTimer() {
        timer.upstream.connect().cancel()
    }
    
    func startTimer() {
        timer = Timer.publish(every: 0.3, on: .main, in: .common).autoconnect()
    }
    
    
    
    var body: some View {
        
        
        
        Button(action: {
            
            // your logic!
            
        }){
            
            ZStack
            {
                
                
                Circle()
                    .fill(RadialGradient(gradient: Gradient(colors: [Color(UIColor.systemTeal), Color.white.opacity(0.1)]), center: .center, startRadius: 0, endRadius: 400))
                    .frame(width: random2*500, height: random2*500)
                
                Circle()
                    .fill(RadialGradient(gradient: Gradient(colors: [Color(UIColor.gray), Color.white.opacity(0.01)]), center: .center, startRadius: 0, endRadius: 400))
                    .frame(width: random1*400, height: random1*400)
                
                
                Circle()
                    .fill(RadialGradient(gradient: Gradient(colors: [Color(UIColor.systemTeal), Color.white.opacity(0.1)]), center: .center, startRadius: 150, endRadius: 190))
                    .frame(width: 200, height: 200)
                
                Image(systemName: "waveform")
                    .resizable()
                    .frame(width: 100, height: 100)
                
                
            }
            
            .scaleEffect(startAnimation ? random1 : 1 )
            .animation(.easeInOut)
            .onTapGesture {
                startAnimation.toggle()
                
                if startAnimation == false
                {
                    stopTimer()
                    
                }
                else
                {
                    startTimer()
                }
                
            }
            
            
        }
        .onReceive(timer) { _ in
            random1 = CGFloat.random(in: 0.5...1)
            random2 = CGFloat.random(in: 0.5...1)
            print(random1, random2)
        }
        .onAppear()
        {
            stopTimer()
        }
        
        
        
        
    }
    
}

enter image description here