我有一个在我的应用程序上运行的计时器,它使用保存和重新加载功能,当用户离开视图并返回到视图时。但是,如果我转到我的应用程序上的其他选项卡,该选项卡所需的操作似乎打破了计时器。
这是因为应用程序中的线程使用情况以及另一个选项卡的coredata会导致计时器计数?这是我的计时器代码
更新2:这是我修改后的计时器代码...
// MARK: - SETTING UP SETS & TIMERS
func createStopTimeForRestFromUserTime(userTime: Int) -> Date {
let calendar = Calendar.current
let stopDate = calendar.date(byAdding: .second, value: userTime, to: Date())
return stopDate!
}
func createTimer(stopDate: Date) {
print("CONSTRUCTING A TIMER")
userDefaults.set(stopDate, forKey: "setStopDate")
restTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(RestController.updateRestTimer), userInfo: nil, repeats: true)
}
func updateRestTimer() {
let presentTime = Date()
let stoppedTime = UserDefaults.standard.object(forKey: "setStopDate") as? Date
if stoppedTime?.compare(presentTime) == ComparisonResult.orderedDescending {
restRemainingCountdownLabel.text = dateComponentsFormatter.string(from: presentTime, to: stoppedTime!)
} else {
self.stopTimer()
print("THE TIMER IS NOW FINISHED")
}
}
func stopTimer() {
self.restTimer.invalidate()
}
// MARK: - CONFIGURE TIMER ON OPEN / CLOSE
override func viewWillDisappear(_ animated: Bool) {
print("VIEWWILLDISAPPEAR WAS CALLED")
stopTimer()
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ViewDidChangeNotification"), object: NSDate())
}
func handleResumedTime(disappTime: NSDate) {
let disappearedTime = disappTime
let resumeTime = NSDate()
if disappearedTime.compare(resumeTime as Date) == ComparisonResult.orderedDescending {
print("RESUMING THE TIMER")
self.createTimer(stopDate: disappearedTime as Date)
} else {
print("TIMER HAS FINISHED")
stopTimer()
}
}
func handleTimerCallback(notification: NSNotification) {
if let date = notification.object as? NSDate {
self.handleResumedTime(disappTime: date)
}
}
备用VC id切换中的代码导致破坏:
override func viewDidLoad() {
NotificationCenter.default.addObserver(self, selector: #selector(RoutineController.handleTimerCallback(notification:)), name: NSNotification.Name(rawValue: "ViewDidChangeNotification"), object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "ViewDidChangeNotification"), object: NSDate())
}
func handleTimerCallback(notification: NSNotification) {
let date = notification.object
print("Object is \(date)")
}
编辑:添加更新的handleResumed func和控制台打印输出更改标签并再次更改时...
func handleResumedTime(disappTime: NSDate) {
let disappearedTime = disappTime as Date
let resumeTime = NSDate() as Date
print("ATTEMPTING RESUME")
print(disappearedTime)
print(resumeTime)
if resumeTime.compare(disappearedTime) == ComparisonResult.orderedAscending {
print("RESUMING THE TIMER")
self.createTimer(stopDate: disappearedTime)
} else {
print("TIMER HAS FINISHED")
stopTimer()
}
}
答案 0 :(得分:0)
尝试使用DateFormatter
比较计时器(以毫秒为单位),并使用Notifications
在控制器之间传递数据。
每次切换标签时都会调用此函数。它使计时器无效,停止计时,并以毫秒为单位节省时间。
override func viewWillDisappear(_ animated: Bool) {
restTimer.invalidate()
let df = DateFormatter()
df.dateFormat = "y-MM-dd H:m:ss.SSSS"
let disappearingDate = Date()
let disappearingDateInMilliseconds = df.string(from: disappearingDate)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "kViewDidChangeExampleNotification"), object: disappearingDateInMilliseconds)
}
/* add your Notification observers in each view controller */
override func viewDidLoad() {
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.handleTimerCallback(notification:)), name: NSNotification.Name(rawValue: "kViewDidChangeExampleNotification"), object: nil)
}
您需要定义将处理每个控制器中的通知的函数:
func handleTimerCallback(notification: NSNotification) {
if let dateString = notification.object as? String {
print("Object is an String: \(notification.object)")
resumeTimerWithDate(dateString)
} else {
print("Object is not of type String: \(notification.object)")
}
}
比较Swift中的日期的快速示例:毫秒:
func resumeTimerWithDate(dateString: String) {
let df = DateFormatter()
df.dateFormat = "y-MM-dd H:m:ss.SSSS"
let secondDate = Date()
let secondDateToStr = df.string(from: secondDate)
if dateString < secondDateToStr {
print("RESUMING THE TIMER")
let resumeDate = df.date(from: dateString)
self.createTimer(resumeDate)
} else {
print("TIMER HAS FINISHED")
}
}
需要考虑的其他事项:您可能希望添加一些打印语句以进行调试/健全性检查,因为某些功能可能会先触发其他功能。例如,您可以尝试在viewWillDisappear
或viewDidDisappear
中发布通知,而不是在prepare(for segue:)
中发布通知。