Files
multi-chrono-ios/MultiChrono/Stopwatch.swift

83 lines
2.0 KiB
Swift

//
// Stopwatch.swift
// MultiChrono
//
// Created by Beatrice Dellacà on 26/01/26.
//
import Foundation
import Combine
class Stopwatch: ObservableObject, Identifiable {
let id = UUID()
@Published var name: String
@Published var elapsedTime: TimeInterval = 0
@Published var isRunning: Bool = false
private var timer: AnyCancellable?
private var startTime: Date?
private var accumulatedTime: TimeInterval = 0
init(name: String) {
self.name = name
}
deinit {
timer?.cancel()
}
func start() {
guard !isRunning else { return }
startTime = Date()
isRunning = true
timer = Timer.publish(every: 0.1, on: .main, in: .common)
.autoconnect()
.sink { [weak self] _ in
self?.tick()
}
}
func pause() {
guard isRunning else { return }
timer?.cancel()
timer = nil
if let startTime = startTime {
accumulatedTime += Date().timeIntervalSince(startTime)
}
isRunning = false
startTime = nil
// Ensure UI shows accurate accumulated time
elapsedTime = accumulatedTime
}
func reset() {
pause()
accumulatedTime = 0
elapsedTime = 0
}
private func tick() {
guard let startTime = startTime else { return }
elapsedTime = accumulatedTime + Date().timeIntervalSince(startTime)
}
var formattedTime: String {
let hours = Int(elapsedTime) / 3600
let minutes = Int(elapsedTime) / 60 % 60
let seconds = Int(elapsedTime) % 60
let tenths = Int((elapsedTime.truncatingRemainder(dividingBy: 1)) * 10)
if hours > 0 {
return String(format: "%02i:%02i:%02i.%01i", hours, minutes, seconds, tenths)
} else {
return String(format: "%02i:%02i.%01i", minutes, seconds, tenths)
}
}
}