How to make a countdown to date Swift

2020-05-21 06:24发布

I was facing the struggle of making a timer app, so I thought that now that I solved it I could help others who face the problem. So basically this app counts down to a specific date from the current time. As stack overflow allows a Q and A format I hope that can help you. See the comments for explanations.

标签: swift timer
4条回答
我欲成王,谁敢阻挡
2楼-- · 2020-05-21 07:07

Cleaned up/updated for latest Swift version of the accepted answer.

    // here we set the current date

    let date = NSDate()
    let calendar = Calendar.current

    let components = calendar.dateComponents([.hour, .minute, .month, .year, .day], from: date as Date)

    let currentDate = calendar.date(from: components)

    let userCalendar = Calendar.current

    // here we set the due date. When the timer is supposed to finish
    let competitionDate = NSDateComponents()
    competitionDate.year = 2017
    competitionDate.month = 4
    competitionDate.day = 16
    competitionDate.hour = 00
    competitionDate.minute = 00
    let competitionDay = userCalendar.date(from: competitionDate as DateComponents)!

    //here we change the seconds to hours,minutes and days
    let CompetitionDayDifference = calendar.dateComponents([.day, .hour, .minute], from: currentDate!, to: competitionDay)


    //finally, here we set the variable to our remaining time
    let daysLeft = CompetitionDayDifference.day
    let hoursLeft = CompetitionDayDifference.hour
    let minutesLeft = CompetitionDayDifference.minute

    print("day:", daysLeft ?? "N/A", "hour:", hoursLeft ?? "N/A", "minute:", minutesLeft ?? "N/A")

    //Set countdown label text
    countDownLabel.text = "\(daysLeft ?? 0) Days, \(hoursLeft ?? 0) Hours, \(minutesLeft ?? 0) Minutes"
查看更多
Deceive 欺骗
3楼-- · 2020-05-21 07:09

Cleaned up and updated with countdown computed on a timer and leading zero String format.

    let futureDate: Date = {
        var future = DateComponents(
            year: 2020,
            month: 1,
            day: 1,
            hour: 0,
            minute: 0,
            second: 0
        )
        return Calendar.current.date(from: future)!
    }()

    var countdown: DateComponents {
        return Calendar.current.dateComponents([.day, .hour, .minute, .second], from: Date(), to: futureDate)
    }

    @objc func updateTime() {
        let countdown = self.countdown //only compute once per call
        let days = countdown.day!
        let hours = countdown.hour!
        let minutes = countdown.minute!
        let seconds = countdown.second!
        countdownLabel.text = String(format: "%02d:%02d:%02d:%02d", days, hours, minutes, seconds)
    }

    func runCountdown() {
        Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
    }
查看更多
贪生不怕死
4楼-- · 2020-05-21 07:12

This worked for me. The only thing that troubles me is that it doesn't really countdown as the user has to refresh the page for it to recount. You can see it "counting" when the user is scrolling up and down cells on a UITableView as the cells do refresh the view. Another thing is that I have on NSTimeZone of the currentDate "GMT+2:00" as it works for my time but only because I haven't figured out how to use the device NSTimeZone yet.

    let releaseDate = "2015-05-02'T'22:00:00:000Z"
    let futureDateFormatter = NSDateFormatter()
    futureDateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
    let date: NSDate = futureDateFormatter.dateFromString(releaseDate!)!

    let currentDate = NSDate();
    let currentFormatter = NSDateFormatter();
    currentFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
    currentFormatter.timeZone = NSTimeZone(abbreviation: "GMT+2:00")

    let diffDateComponents = NSCalendar.currentCalendar().components([NSCalendarUnit.Month, NSCalendarUnit.Day, NSCalendarUnit.Hour, NSCalendarUnit.Minute], fromDate: currentDate, toDate: date, options: NSCalendarOptions.init(rawValue: 0))

    let countdown = "\(diffDateComponents.month) m: \(diffDateComponents.day) d: \(diffDateComponents.hour) h: \(diffDateComponents.minute) min"
查看更多
We Are One
5楼-- · 2020-05-21 07:19

Here is the solution of how I managed to create a countdown timer to a specific NSDate, for SO allows Q and A Style Answers.

// here we set the current date

 let date = NSDate()
    let calendar = NSCalendar.currentCalendar()
    let components = calendar.components(.CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitMonth | .CalendarUnitYear | .CalendarUnitDay, fromDate: date)
    let hour = components.hour
    let minutes = components.minute
    let month = components.month
    let year = components.year
    let day = components.day



    let currentDate = calendar.dateFromComponents(components)

  // here we set the due date. When the timer is supposed to finish  

    let userCalendar = NSCalendar.currentCalendar()


    let competitionDate = NSDateComponents()
    competitionDate.year = 2015
    competitionDate.month = 6
    competitionDate.day = 21
    competitionDate.hour = 08
    competitionDate.minute = 00
    let competitionDay = userCalendar.dateFromComponents(competitionDate)!


// Here we compare the two dates 
    competitionDay.timeIntervalSinceDate(currentDate!)

    let dayCalendarUnit: NSCalendarUnit = (.CalendarUnitDay | .CalendarUnitHour | .CalendarUnitMinute)

//here we change the seconds to hours,minutes and days
    let CompetitionDayDifference = userCalendar.components(
        dayCalendarUnit, fromDate: currentDate!, toDate: competitionDay,
        options: nil)
  //finally, here we set the variable to our remaining time  
    var daysLeft = CompetitionDayDifference.day
    var hoursLeft = CompetitionDayDifference.hour
    var minutesLeft = CompetitionDayDifference.minute

Hope that helps you guys if you're facing the same struggle as I have

查看更多
登录 后发表回答