Таймер обратного отсчета до даты выпуска - PullRequest
0 голосов
/ 07 февраля 2019

Привет! Я пытаюсь обработать этот код, и моя проблема связана с частью кода:

countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: (Any).self, selector: #selector(updateTime), userInfo: nil, repeats: true)

- это сообщение об ошибке в Xcode

Аргумент '#selector'не может ссылаться на глобальную функцию updateTime ()

И я не могу справиться с этим.что может быть не так?спасибо

import UIKit
import Foundation
var releaseDate: NSDate?
var countdownTimer = Timer()

func startTimer() {

    let releaseDateString = "2019-02-23 08:00:00"
    let releaseDateFormatter = DateFormatter()
    releaseDateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    releaseDate = releaseDateFormatter.date(from: releaseDateString)! as NSDate

    countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: (Any).self, selector: #selector(updateTime), userInfo: nil, repeats: true)
}

func updateTime() {

    let currentDate = Date()
    let calendar = Calendar.current

    let diffDateComponents = calendar.dateComponents([.day, .hour, .minute, .second], from: currentDate, to: releaseDate! as Date)

    let countdown = "Days \(diffDateComponents.day ?? 0), Hours \(diffDateComponents.hour ?? 0), Minutes \(diffDateComponents.minute ?? 0), Seconds \(diffDateComponents.second ?? 0)"

    print(countdown)
}

1 Ответ

0 голосов
/ 07 февраля 2019

Вы не можете использовать глобальную функцию в #selector.Так что переместите это в класс.Кроме того, если вы собираетесь использовать таймер на основе селектора, updateTime должен быть помечен как @objc.

В качестве альтернативы, если вы действительно хотите использовать глобальные функции, просто используйте таймер на основе блоков:

var releaseDate: Date?
var countdownTimer = Timer()

func startTimer() {
    let releaseDateString = "2019-02-23 08:00:00"
    let releaseDateFormatter = DateFormatter()
    releaseDateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
    releaseDate = releaseDateFormatter.date(from: releaseDateString)

    countdownTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
        updateTime()
    }
}

func updateTime() {
    let currentDate = Date()
    let calendar = Calendar.current

    let diffDateComponents = calendar.dateComponents([.day, .hour, .minute, .second], from: currentDate, to: releaseDate!)

    let countdown = "Days \(diffDateComponents.day ?? 0), Hours \(diffDateComponents.hour ?? 0), Minutes \(diffDateComponents.minute ?? 0), Seconds \(diffDateComponents.second ?? 0)"

    print(countdown)
}

Но было бы лучше поместить это в struct или class, чтобы избежать загрязнения вашего глобального пространства имен.

(Плюс, я не уверен, почему вы используетеNSDate ... Я бы предложил остаться с Date объектами.)


Лично я бы сделал что-то вроде:

class TimerManager {
    var releaseDate: Date?

    private weak var countdownTimer: Timer?

    private let formatter: DateComponentsFormatter = {
        let formatter = DateComponentsFormatter()
        formatter.unitsStyle = .full
        formatter.allowedUnits = [.day, .hour, .minute, .second]
        return formatter
    }()

    deinit {
        countdownTimer?.invalidate()
    }

    func startTimer() {
        releaseDate = DateComponents(calendar: .current, year: 2019, month: 2, day: 23, hour: 8).date

        countdownTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { [weak self] _ in
            self?.updateTime()
        }
    }

    private func updateTime() {
        guard let releaseDate = releaseDate,
            let string = formatter.string(from: Date(), to: releaseDate) else { return }
        print(string)
    }
}

Это не только заботитсяиз проблем Timer, но также избавляет вас от необходимости вручную создавать эти отформатированные строки компонентов разницы дат.

...