Circular timer, iOS devices (swift) with Lottie
PART I
Step 1
Create a new project for single view application from Xcode. Then give a name to your application like “animated_timer”.
Step 2
Install lottie library to your pod file
pod 'lottie-ios'
Step 3
Restart your Xcode project with opening workspace of your application
Step 4
The next step is download animation (*.json file) for your timer from this link. And move the file to your application directory with the nam ‘timer_lottie.json’.
PART II
Now we have all prerequisites to start coding part (Thank god)
Step 1
Create a view which is called ‘CircularTimerView’
import UIKit
import Lottiepublic class CircularTimerView: UIView {
}
Step 2
Initialise variables
Step 3
Insert following codes line by line inside your view
public convenience init(time: Int) {
self.init(frame: .zero)
self.totalTime = time
animationView.animationSpeed = self.speed
updateTime() // this function is coming in next lines
}
public override init(frame: CGRect) {
super.init(frame: frame)
let animation: Animation = Animation.named("timer_lottie")!
animationView.animation = animation animationView.animationSpeed = self.speed
timerIndicator.textAlignment = .center
timerIndicator.text = "0:00:00".uppercased()
timerIndicator.font = UIFont.boldSystemFont(ofSize: 15)
self.addSubview(animationView)
self.addSubview(timerIndicator)
}public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
public override func layoutSubviews() {
super.layoutSubviews()
animationView.frame = self.bounds
let h: CGFloat = self.frame.height / 10
let w: CGFloat = self.frame.width - 20
let x: CGFloat = (self.frame.width - w) / 2
let y: CGFloat = (self.frame.height - h) / 2
timerIndicator.frame = CGRect(x: x, y: y, width: w, height: h)
}
public func start() {
if state == .running {
return
} self.state = .running
timer = Timer.scheduledTimer(withTimeInterval: 1 / 60, repeats: true, block: { (t) in
self.currentMseconds = self.currentMseconds + 1
self.updateTime()
}) self.animationView.play(fromProgress: 0, toProgress: 450, loopMode: .playOnce) { (isFinished) in
print("is Finished \(isFinished)")
}
}@objc func updated() {
if self.currentMseconds == self.totalTimeInMilliseconds {
self.stop()
}
}
public func stop() {
if state == .stopped {
return
}self.state = .stopped
self.currentMseconds = 0
if self.animationView.isAnimationPlaying {
self.animationView.stop()
}self.timer?.invalidate()
self.timer = nil
}public func pause() {
if state == .paused {
return
} self.state = .paused
if self.animationView.isAnimationPlaying {
self.animationView.pause()
} let availableTime = self.currentMseconds
let min = availableTime / (60 * 60)
let sec = availableTime / 60
let msec = availableTime - sec * 60 self.onPause?(min, sec, msec)
self.timer?.invalidate()
self.timer = nil
}private func updateTime() {
let availableTime = self.totalTimeInMilliseconds - self.currentMseconds
let min = availableTime / (60 * 60)
let minText: String = min >= 10 ? "\(min)" : "0\(min)"
let sec = availableTime / 60
let secText: String = sec >= 10 ? "\(sec)" : "0\(sec)"
let msec = availableTime - sec * 60
let msText: String = msec >= 10 ? "\(msec)" : "0\(msec)" self.timerIndicator.text = ("\(minText):\(secText):\(msText)")
self.updated()}
PART III
Now we have timer view (CircularTimerView), and we can use from this view in our controller
Step 1
import UIKitpublic class ViewController: UIViewController {
private let timerView = CircularTimerView(time: 11)
private let stopButton = UIButton()
private let pauseButton = UIButton()
private let startButton = UIButton()
private let actionView = UIView()
private let resultIndicatorLabel = UILabel()
}
enum TimerState {case initialcase runningcase pausedcase stopped}
In view did load method write the following lines
In the viewDidLayoutSubviews method write the following lines
And the last step is
This is the end of the project
The output should be like this