Reputation: 1253
I am making a countdown component to an app I am updating. I finally got it working but when it is on my simulator or when I run it through my phone, it bogs down and skips seconds, sometimes freezing my screen and not allowing me to change views and such. This is my code below. I am curious why this is happening.
Thank you in advance!
class CountdownViewController: UIViewController {
@IBOutlet weak var days: UILabel!
@IBOutlet weak var hours: UILabel!
@IBOutlet weak var minutes: UILabel!
@IBOutlet weak var seconds: UILabel!
var timer:NSTimer!
func reloadData(){
self.viewDidLoad()
}
override func viewDidLoad() {
super.viewDidLoad()
self.timer = NSTimer(timeInterval: 0.5, target: self, selector: Selector("reloadData"), userInfo: nil, repeats: true)
NSRunLoop.currentRunLoop().addTimer(self.timer, forMode: NSRunLoopCommonModes)
self.canDisplayBannerAds = true
// here we set the current date
let date = NSDate()
let calendar = NSCalendar.currentCalendar()
let components = calendar.components(.CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitMonth | .CalendarUnitYear | .CalendarUnitDay | .CalendarUnitSecond, fromDate: date)
let hour = components.hour
let minute = components.minute
let month = components.month
let year = components.year
let day = components.day
let second = components.second
let currentDate = calendar.dateFromComponents(components)
// here we set the due date. When the timer is supposed to finish
let userCalendar = NSCalendar.currentCalendar()
let electionDate = NSDateComponents()
electionDate.year = 2016
electionDate.month = 11
electionDate.day = 08
electionDate.hour = 00
electionDate.minute = 00
electionDate.second = 00
let electionDay = userCalendar.dateFromComponents(electionDate)!
// Here we compare the two dates
electionDay.timeIntervalSinceDate(currentDate!)
let dayCalendarUnit: NSCalendarUnit = (.CalendarUnitDay | .CalendarUnitHour | .CalendarUnitMinute | .CalendarUnitSecond)
//here we change the seconds to hours,minutes and days
let electionDayDifference = userCalendar.components(dayCalendarUnit, fromDate: currentDate!, toDate: electionDay,options: nil)
//finally, here we set the variable to our remaining time
var daysLeft = electionDayDifference.day
var hoursLeft = electionDayDifference.hour
var minutesLeft = electionDayDifference.minute
var secondsLeft = electionDayDifference.second
days.text = String(daysLeft)
hours.text = String(hoursLeft)
minutes.text = String(minutesLeft)
seconds.text = String(secondsLeft)
}
Upvotes: 0
Views: 1106
Reputation: 285059
It's a kind of delegate method which is called (once) by the view controller and is designated for setting up things once.
Put your code to be executed after the timer fires in a custom function.
It's not necessary to create the timer again and again, setting the parameter repeats
to true
calls the selector periodically.
Upvotes: 0
Reputation: 3397
You are adding more and more timers to RunLoop every 0.5 seconds. And they are all fired at once, causing performance degradation over time. You need to move all code below // here we set the current date
comment to reloadData
function and remove self.viewDidLoad()
from there, and everything should be fine. Your timer will be scheduled only once and will call reloadData
every 0.5 seconds repeatedly (because you created it with repeats: true
parameter).
Upvotes: 3