Вчера я создал таймер и установил время по типу:
3 дня - 24 часа - 60 мин - 59 сек
Запустил таймер и время пошло обратным отчетом.
Закрыл таймер.
Открыл таймер сегодня и время начало идти с того момента когда было закрыто приложение.
Как сделать так, чтобы при открытии приложения отчет времени начинался с реально прошедшего времени? Ну, типа таймер при закрытии приложения не останавливался)
Таймер. Хочу знать все!)
Время само по себе не останавливается, зачем какой то таймер бекграунде ещё крутить? Проще запомнить дату начало отсчета и потом вычитать её из текущей, тем самым получая реально прошедшее время с начала отсчета.
Как сделать что бы при выходе или при закрытии приложения сохранялась текущая дата, а при открытии приложения, от текущей даты отнять сохраненную дату? Что бы по итогу получить разницу в годах, месяцах, днях, час, минутах, секундах - все Int.
Сохранить как и сказали в UserDefaults, а разницу календарь знает:
let start = Date()
let end = start.addingTimeInterval(5 * 24 * 60 * 60)
let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: start, to: end)
print("""
year: \(components.year!)
month: \(components.month!)
day: \(components.day!)
hour: \(components.hour!)
minute: \(components.minute!)
second: \(components.second!)
""")
Что то начинаю подтупливать))
У меня есть переменные:
var timer = Timer()
private var year1000 = 1000
private var year1 = 100
private var month1 = 12
private var days1 = 30
private var hour1 = 24
private var min1 = 60
private var sec1 = 59
и есть метод который вставляет туда значения
@objc func CLOCK() {
if SECONDS >= 1 {
SECONDS = SECONDS - 1
secondsLabel.text = String("\(SECONDS) секунд")
}
if sec1 >= 0 {
sec1 = sec1 - 1
secLabel.text = String("\(sec1)")
minLabel.text = String("\(min1)")
hourLabel.text = String("\(hour1)")
dayssLabel.text = String("\(days1)")
monthhLabel.text = String("\(month1)")
yearssLabel.text = String("\(year1000)\(YEARS)")
}
if sec1 == 0 {
min1 = min1 - 1
sec1 = 60
}
if min1 == 0 {
hour1 = hour1 - 1
min1 = 60
}
if hour1 == 0 {
days1 = days1 - 1
hour1 = 24
}
if days1 == 0 {
month1 = month1 - 1
days1 = 30
}
if month1 == 0 {
year1 = year1 - 1
month1 = 30
}
}
// запускаю таймер
if YEARS == result {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.CLOCK), userInfo: nil, repeats: true)
}
после этого label отображают эти данные таймера с обратным отсчетом :
year1000 = 1000
year1 = 100
month1 = 12
days1 = 30
hour1 = 24
min1 = 60
sec1 = 59
теперь когда пользователь закрывает приложение надо что бы эти данные сохранились (не понимаю этот момент)
и потом когда открываем приложение получаем разницу (не понимаю этот момент)
let start = Date()
let end = start.addingTimeInterval(5 * 24 * 60 * 60)
let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: start, to: end)
вычитаем ее от сюда
year1000 = 1000
year1 = 100
month1 = 12
days1 = 30
hour1 = 24
min1 = 60
sec1 = 59
?
Я точно не знаю, как делают правильно, но за сегодня я понял так (на примере прогрузки вью контроллера):
var timer = Timer()
let year1000: Int = 1000
let year1 = 100
let month1 = 12
let days1 = 30
let hour1 = 24
let min1 = 3
let sec1 = 59
var futureDate: Date!
override func viewDidLoad() {
super.viewDidLoad()
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .full
dateFormatter.timeStyle = .full
if let dateString = UserDefaults.standard.string(forKey: "futureDate"), let date = dateFormatter.date(from: dateString) {
futureDate = date
} else {
futureDate = Calendar.current.date(byAdding: .init(era: year1000, year: year1, month: month1, day: days1, hour: hour1, minute: min1, second: sec1), to: Date())
let futureDateString = dateFormatter.string(from: futureDate)
UserDefaults.standard.set(futureDateString, forKey: "futureDate")
}
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateLabels), userInfo: nil, repeats: true)
timer.fire()
}
@objc func updateLabels () {
let components = Calendar.current.dateComponents([.era,.year,.month,.day,.hour,.minute,.second], from: Date(), to: futureDate)
era.text = components.era?.description
year.text = components.year?.description
month.text = components.month?.description
day.text = components.day?.description
hour.text = components.hour?.description
minute.text = components.minute?.description
second.text = components.second?.description
if components.minute == 57 { // любая другая логика
timer.invalidate()
UserDefaults.standard.removeObject(forKey: "futureDate")
}
}
Если делают не так, или вы наблюдаете печальную практику в коде выше, пожалуйста, укажите на это. Мне бы было очень полезно знать.