Created
September 3, 2019 10:25
-
-
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)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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) | |
} | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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