Home > other >  Clock Box Animation with SwiftUI
Clock Box Animation with SwiftUI

Time:11-02

I want to create an animation like showed in this video.

I already created a view that shows the current time, splitted in three boxes, but I dont know how to animate it. Thank you for your help!

This is my enviroment object, which gets the current time:


import SwiftUI


class TimeManager: ObservableObject {
    @Published var date = Date()
    @Published var oldDate = Date()

    func timeString(timeFormat: String, date: Date) -> String {
        let formatter = DateFormatter()
        formatter.dateFormat = timeFormat
        
        let time = formatter.string(from: date)
        return time
    }
    
    // update time
    var updateTimer: Timer {
        withAnimation(.spring()){
            Timer.scheduledTimer(withTimeInterval: 1, repeats: true,
                                 block: {_ in
                
                self.oldDate = self.date
                self.date = Date()
                
            })
        }
    }
}

And this is the view, which splits the time in boxes:

struct BoxesView: View {
    
    @EnvironmentObject var timeManager: TimeManager
    
    var body: some View {
        
        HStack(spacing: 30) {
            
            let timeElements = splitUpTime()
            
            ForEach(timeElements, id: \.self) { timeElement in
                SingleBoxElement(text: timeElement)
            }
            
            
        }.ignoresSafeArea()
    }
    
    func splitUpTime() -> Array<String> {
        
        let splitDate = timeManager.timeString(timeFormat: "HH:mm:ss", date: timeManager.date).components(separatedBy: ":")
        
        return splitDate
    }
}

struct SingleBox: View {
    
    let text: String
    
    var body: some View {
            
            ZStack {
                
                RoundedRectangle(cornerRadius: 12)
                    .foregroundColor(.pink)
                
                Text(text)
                    .foregroundColor(.white)
                    .font(.title)
                    .fontWeight(.semibold)
                    .monospacedDigit()
                
                
            }.frame(width: 90, height: 90)
    }
}


CodePudding user response:

Here's a quick example --

On each tap of the "Next" button, it increments the value... sliding the "old" string down-and-out the bottom and the "new" string down-and-in from the top:

import SwiftUI

struct TextTransition: View {
    @State private var secondsValue = "21"
    @State private var seconds: Int = 21

    var body: some View {
        VStack (spacing: 50) {
            ZStack {
                Text(secondsValue)
                    .font(.title)
                    .fontWeight(.semibold)
                    .monospacedDigit()
                    .foregroundColor(Color.white)
                    .frame(width: 60, height: 40)
                    .transition(AnyTransition.asymmetric(insertion: .move(edge: .top), removal: .move(edge: .bottom)))
                    .id("Seconds"   secondsValue)
            }
            .background(Color.red)
            .frame(width: 60, height: 40)
            .clipped()
            
            Button("Next") {
                seconds  = 1
                withAnimation (.easeInOut(duration: 0.5)) {
                    self.secondsValue = "\(seconds)"
                }
            }
        }
    }

}

Now all you need to do is implement your TimeManager to update secondsValue (and minutes and hours values for their Text elements).

  • Related