Search code examples
swifttimercountdownnsdatecomponents

Timer to countdown for 6 hours and stop when time is reached and then start again for another 6 hours when button is pressed


I need a timer to countdown for 6 hours.

.It has to reset when the time is reached

.It has to be activated when a button is pressed.

.It has to continue to run while the app is both open or closed.

I have one countdown timer to a date and have another countdown timer which only works while the app is active.

How do I make a timer which counts for 6 hours?

Timer countdown to date ⬇︎

var timeCount: NSDate?
var timer = Timer()

timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(countdown), userInfo: nil, repeats: true)

@objc func countdown()
{
let endTime = "08-10-2020 18:00:00"
let formatter = DateFormatter()
formatter.dateFormat = "dd-MM-yyyy HH:mm:ss"
timeCount = (formatter.date(from: endTime))! as NSDate

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

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

let countdown = "\(diffDateComponents.hour ?? 0):\(diffDateComponents.minute ?? 0):\(diffDateComponents.second ?? 0)"

let hourS = diffDateComponents.hour!
let minuteS = diffDateComponents.minute!
let secondS = diffDateComponents.second!

print(countdown)

if countdown == "0:0:0"
{
   button.setTitle("PRESS", for: .normal)
   button.backgroundColor = .green
   timer.invalidate()
}
else
{
   button.setTitle("PRESS WHEN TIME RUNS OUT" + "\n\(String(format: "%02d:%02d:%02d", hourS, minuteS, secondS))", for: .normal)
   button.backgroundColor = .red
}
}

Timer countdown only while app is active ⬇︎

var timer = Timer()
var hours = 06
var minutes = 00
var secs = 00


timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(countdown), userInfo: nil, repeats: true)

@objc func countdown()
{
    secs = secs-1
    if (secs<0)
    {
        secs = 59
        minutes=minutes-1
        if (minutes<0)
        {
            minutes = 59
            hours = hours-1
            if (hours<0)
            {
                hours = 0
                minutes = 0
                secs = 0
                
                timer.invalidate()
            }
        }
    }

var hourp: String
var minutesp: String
var secp: String
    
if(hours<10)
{
hourp = "0" + String(describing: hours)
}
else
{
hourp = String(describing: hours)
}
if(minutes<10)
{
minutesp = "0" + String(describing: minutes)
}
else
{
minutesp = String(describing: minutes)
}
if(secs<10)
{
secp = "0" + String(describing: secs)
}
else
{
secp = String(describing: secs)
}
let timing = hourp + ":" + minutesp + ":" + secp
    
print(timing)

if hours == 0 && minutes == 0 && secs == 0
{
button.setTitle("PRESS", for: .normal)
button.backgroundColor = .green
else
{
button.setTitle("PRESS WHEN TIME RUNS OUT" + "\n\(timing)" , for: .normal)
button.backgroundColor = .red
}

}

Solution

  • This is what I ended up having to do for it to work for me as intended.

    Thanks to the answer from @Burak Köse for steering me in the right direction.

    import UIKit
    import Foundation
    
    var timer = Timer()
    var currentTime = Date()
    var compareTime = Date().addingTimeInterval(-21600)
    
    
    func setupButtonTitle()
    {
     if UserDefaults.standard.object(forKey: "count6") == nil
        {
            button.setTitle("PRESS", for: .normal)
            button.backgroundColor = .green
        }
        else
        {
            button.setTitle("PRESS" + "\nIN " + "\(startTimer()))" , for: .normal)
        }
      button.addTarget(self, action: #selector(buttonTap), for: .touchUpInside)
    }
    
    
    func startTimer()
    {
      timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(sixHourCountdown), userInfo: nil, repeats: true)
    }
    
    @objc func sixHourCountdown()
    {
        let timeStarted = UserDefaults.standard.object(forKey: "count6")
        
        let timeStart = timeStarted as! Date
        let diffComponents = Calendar.current.dateComponents([.hour, .minute, .second], from: compareTime, to: timeStart)
        let hour = diffComponents.hour!
        let minute = diffComponents.minute!
        let second = diffComponents.second!
        let timeRemaining = String(format: "%02d:%02d:%02d", hour, minute, second)
    
        compareTime += 1
        
        if hour == 0 && minute == 0 && second == 0 || timeStart < compareTime
        {
            button.setTitle("PRESS", for: .normal)
            button.backgroundColor = .green
            timer.invalidate()
        }
        else
        {
            button.setTitle("PRESS IN" + "\n\(timeRemaining)", for: .normal)
        }
    }
    
    
    @objc func buttonTap()
    {
        if button.currentTitle != "PRESS"
        {
            button.backgroundColor = .red
            DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2), execute:
            {
             button.backgroundColor = .yellow
            })
        }
        if button.currentTitle == "PRESS" && button.backgroundColor == .green
        {
            UserDefaults.standard.set(currentTime, forKey: "count6")
    
            let otherVC = OTHERVC()
            self.navigationController?.pushViewController(otherVC, animated: true)
        }
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
    
    setupButtonTitle()