Circular timer, iOS devices (swift) with Lottie

Mukhammadjon Tokhirov
4 min readJul 13, 2019

--

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 Lottie
public class CircularTimerView: UIView {
}

Step 2

Initialise variables

public var state: TimerState = .stady’ went wrong it should change to ‘* = .initial’

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

View did load method

In the viewDidLayoutSubviews method write the following lines

View did load subviews

And the last step is

On click method

This is the end of the project

The output should be like this

--

--

Responses (2)