Skip to content

Instantly share code, notes, and snippets.

@raunakp
Created September 3, 2019 10:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raunakp/2ec6abdfc1efe692ee1d41792c073e1f to your computer and use it in GitHub Desktop.
Save raunakp/2ec6abdfc1efe692ee1d41792c073e1f to your computer and use it in GitHub Desktop.
a UILabel subclass that automatically updates elapsed time (eg: 1 month 2 weeks ago)
//
// AutoUpdatingTimeElapsedLabel.swift
//
// Created by Raunak Poddar on 03/09/19.
//
import UIKit
@objc class AutoUpdatingTimeElapsedLabel: UILabel {
@objc static let ClockUpdateNotification = Notification.Name("ClockUpdateNotification")
var eventTime: Date? {
didSet {
text = Date().timeElapsedString(sinceDate: eventTime)
}
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
self.commonInit()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.commonInit()
}
func commonInit() {
let center = NotificationCenter.default
let mainQueue = OperationQueue.main
text = Date().timeElapsedString(sinceDate: eventTime)
center.addObserver(forName: AutoUpdatingTimeElapsedLabel.ClockUpdateNotification,
object: nil,
queue: mainQueue) { [weak self] (notification: Notification) in
if let date = notification.userInfo?["date"] as? Date {
self?.text = date.timeElapsedString(sinceDate: self?.eventTime)
}
}
}
}
//
// Date+TimeElapsedString.swift
//
// Created by Raunak Poddar on 03/09/19.
//
import Foundation
extension Date {
private static func elapsedString(forComponent component: Int,
subComponent: Int,
componentSingular: String,
componentPlural: String,
subComponentSingular: String,
subComponentPlural: String) -> String? {
var str: String?
if component > 1 && subComponent > 1 {
str = "\(component) \(componentPlural) \(subComponent) \(subComponentPlural)"
} else if component > 1 && subComponent == 1 {
str = "\(component) \(componentPlural) \(subComponent) \(subComponentSingular)"
} else if component > 1 {
str = "\(component) \(componentPlural)"
} else if component == 1 {
str = "\(component) \(componentSingular)"
}
return str
}
func timeElapsedString(sinceDate since: Date?) -> String {
if since == nil {
return "??"
}
let dcs = Calendar.current.dateComponents([.year, .month, .weekOfMonth, .day, .hour, .minute, .second], from: since!, to: self)
// return "\(dcs.year) \(dcs.month) \(dcs.day) \(dcs.hour) \(dcs.day)"
var str: String?
let year = dcs.year!
let month = dcs.month!
str = Date.elapsedString(forComponent: year,
subComponent: month,
componentSingular: "year",
componentPlural: "years",
subComponentSingular: "month",
subComponentPlural: "months")
if let str = str {
return "\(str) ago"
}
let week = dcs.weekOfMonth!
str = Date.elapsedString(forComponent: month,
subComponent: week,
componentSingular: "month",
componentPlural: "months",
subComponentSingular: "week",
subComponentPlural: "weeks")
if let str = str {
return "\(str) ago"
}
let day = dcs.day!
str = Date.elapsedString(forComponent: week,
subComponent: day,
componentSingular: "week",
componentPlural: "weeks",
subComponentSingular: "day",
subComponentPlural: "days")
if let str = str {
return "\(str) ago"
}
let hour = dcs.hour!
str = Date.elapsedString(forComponent: day,
subComponent: hour,
componentSingular: "day",
componentPlural: "days",
subComponentSingular: "hour",
subComponentPlural: "hours")
if let str = str {
return "\(str) ago"
}
let min = dcs.minute!
str = Date.elapsedString(forComponent: hour,
subComponent: min,
componentSingular: "hour",
componentPlural: "hours",
subComponentSingular: "minute",
subComponentPlural: "minutes")
if let str = str {
return "\(str) ago"
}
let sec = dcs.second!
str = Date.elapsedString(forComponent: min,
subComponent: sec,
componentSingular: "minute",
componentPlural: "minutes",
subComponentSingular: "second",
subComponentPlural: "seconds")
if let str = str {
return "\(str) ago"
}
return "\(sec) seconds ago"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment