Быстрый обратный отсчет дней до выбора даты

Я изо всех сил пытался сделать обратный отсчет в Swift, где он показывает только дни, оставшиеся до некоторой даты, когда вводом является DatePicker... У меня есть опыт работы со Swift, поэтому я некоторое время боролся. Я пробовал здесь несколько похожих ответов, но не сработал, я смотрел учебник, но это обычный обратный отсчет с месяцами, днями, минутами и секундами, это код.

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var timeLabel: UILabel!

let formatter = DateFormatter()
let userCleander = Calendar.current;
let requestedComponent : Set<Calendar.Component> = [
    Calendar.Component.month,
    Calendar.Component.day
]

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(timePrinter), userInfo: nil, repeats: true)

    timer.fire()
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func timeCalculator(dateFormat: String, endTime: String, startTime: Date = Date()) -> DateComponents {
    formatter.dateFormat = dateFormat
    let _startTime = startTime
    let _endTime = formatter.date(from: endTime)

    let timeDifference = userCleander.dateComponents(requestedComponent, from: _startTime, to: _endTime!)
    return timeDifference
}

func timePrinter() -> Void {
    let time = timeCalculator(dateFormat: "MM/dd/yyyy a", endTime: "12/25/2018 a")
    timeLabel.text = "\(time.month!) Months \(time.day!) Days"
}

}

person HDaniel999    schedule 08.03.2018    source источник
comment
Если вам не нужно время, почему вы показываете время? Зачем запускать таймер каждую секунду, если обратный отсчет меняется только один раз в день?   -  person rmaddy    schedule 08.03.2018
comment
Хорошо, rmaddy, спасибо за эту деталь, я меняю код ... Итак, вы знаете, как я могу рассчитать в днях количество лет и месяцев и добавить к общему количеству дней? Танк тебе снова :)   -  person HDaniel999    schedule 08.03.2018


Ответы (1)


Несколько вещей: Не используйте строки для сравнения дат. Используйте объекты даты и операции календаря. (Подробнее об этом через секунду.)

Не запускайте таймер раз в секунду. Сохраните текущую дату по умолчанию пользователя. Когда ваше приложение запускается, сравните сохраненную дату с текущей датой и посмотрите, изменился ли день.

Во время работы слушайте UIApplicationSignificantTimeChange уведомления, а когда получите их, проверьте, не изменилась ли дата.

Что касается сравнения текущей даты с выбранной пользователем датой, у вас есть правильная идея, используя dateComponents(_:from:to:), но вы должны передать компоненты только [.day].

РЕДАКТИРОВАТЬ:

Код, подобный этому, сделает свое дело:

override func viewDidLoad() {
    super.viewDidLoad()
    //Set up the date picker to pick dates, not dates & times
    datePicker.datePickerMode =  .date
    
    //Force the date picker to use midnight today as it's base date and
    //to pick a date at least 1 day in the future
    guard let today = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: Date()),
        let tomorrow = Calendar.current.date(byAdding: .day, value: 1, to: today)
        else {
            return
    }
    datePicker.minimumDate = tomorrow
    datePicker.date = tomorrow
}

@IBAction func datePickerChanged(_ sender: UIDatePicker) {
    let future = datePicker.date
    //Use midnight today as the starting date
    guard let today = Calendar.current.date(bySettingHour: 0, minute: 0, second: 0, of: Date()) else { return }
    
    //Calculate the number of days between today and the user's chosen day.
    let difference = Calendar.current.dateComponents([.day], from: today, to: future)
    guard let days = difference.day else { return }
    let ess = days > 1 ? "s" : ""
    infoLabel.text = "That date is \(days) day\(ess) away."
}
person Duncan C    schedule 08.03.2018
comment
Я собираюсь исправить это прямо сейчас ... Теперь я вижу проблемы, спасибо, Дункан !!! Я обновлю его, как только закончу тестирование. - person HDaniel999; 08.03.2018