如何在后台更新 UILabel 计时器
How to update a UILabel timer after being in background
我正在尝试构建一个简单的计时器,它在活动时工作正常。问题是,如果我在还剩 30 秒时退出应用程序并在 10 秒后返回,这表明我的计时器还剩下大约 28 秒。然后最重要的是,我的通知时间变得一团糟。我一直在尝试许多不同的方法来解决问题,但都无济于事。有人可以帮忙吗?
import UIKit
import AVFoundation
import Foundation
import UserNotifications
class TimerController: UIViewController, UNUserNotificationCenterDelegate {
//MARK: - Variables and Constants
var Minutes = 10.0
var audioPlayer = AVAudioPlayer()
let vc = ViewController()
var isGrantedAccess = false
private var timer = Timer()
let timeInterval = 0.1
//MARK: - IBOutlet
@IBOutlet weak var label: UILabel!
@IBOutlet weak var sliderOutlet: UISlider!
@IBOutlet weak var startOutlet: UIButton!
@IBOutlet weak var stopOutlet: UIButton!
//MARK: - Functions
//MARK: - Notification Alert Functions
func startTimer() {
}
func stopTimer(){
//shut down timer
timer.invalidate()
//clear out any pending and delivered notifications
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
}
func sendNotification() {
let content = UNMutableNotificationContent()
content.title = "Timer Finished"
content.body = "Your escort should be here"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "timer.category"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: Minutes, repeats: false)
let request = UNNotificationRequest(identifier: "timer.request", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
if let error = error{
print("Error posting notification:\(error.localizedDescription)")
}
}
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.actionIdentifier == "stop.action"{
stopTimer()
}
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert,.sound])
}
//MARK: - UIButtons
@IBAction func slider(_ sender: UISlider)
{
Minutes = Double(sender.value)
label.text = String(format: "%.0f", Minutes) + " Minutes"
}
@IBAction func start(_ sender: AnyObject) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(counter), userInfo: nil, repeats: true)
sliderOutlet.isHidden = true
startOutlet.isHidden = true
self.sendNotification()
}
func counter() {
DispatchQueue.main.async {
self.Minutes -= 1
self.label.text = String(format: "%.0f", self.Minutes) + " Minutes"
}
if (Minutes == 0)
{
timer.invalidate()
sliderOutlet.isHidden = false
startOutlet.isHidden = false
}
}
@IBAction func stop(_ sender: AnyObject)
{
timer.invalidate()
Minutes = 0
sliderOutlet.setValue(10, animated: true)
label.text = "0 Minutes"
audioPlayer.stop()
sliderOutlet.isHidden = false
startOutlet.isHidden = false
}
override func viewDidLoad()
{
super.viewDidLoad()
print(vc.isGrantedAccess)
do
{
let audioPath = Bundle.main.path(forResource: "1", ofType: ".mp3")
try audioPlayer = AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath!))
}
catch
{
//ERROR
}
}
进入后台时将 Date() 存储在 NSUserDefaults 中
func applicationDidEnterBackground(_ application: UIApplication) {}
然后在
中进入前台时计算新日期之间的差异
func applicationWillEnterForeground(_ application: UIApplication) {}
我正在尝试构建一个简单的计时器,它在活动时工作正常。问题是,如果我在还剩 30 秒时退出应用程序并在 10 秒后返回,这表明我的计时器还剩下大约 28 秒。然后最重要的是,我的通知时间变得一团糟。我一直在尝试许多不同的方法来解决问题,但都无济于事。有人可以帮忙吗?
import UIKit
import AVFoundation
import Foundation
import UserNotifications
class TimerController: UIViewController, UNUserNotificationCenterDelegate {
//MARK: - Variables and Constants
var Minutes = 10.0
var audioPlayer = AVAudioPlayer()
let vc = ViewController()
var isGrantedAccess = false
private var timer = Timer()
let timeInterval = 0.1
//MARK: - IBOutlet
@IBOutlet weak var label: UILabel!
@IBOutlet weak var sliderOutlet: UISlider!
@IBOutlet weak var startOutlet: UIButton!
@IBOutlet weak var stopOutlet: UIButton!
//MARK: - Functions
//MARK: - Notification Alert Functions
func startTimer() {
}
func stopTimer(){
//shut down timer
timer.invalidate()
//clear out any pending and delivered notifications
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
}
func sendNotification() {
let content = UNMutableNotificationContent()
content.title = "Timer Finished"
content.body = "Your escort should be here"
content.sound = UNNotificationSound.default()
content.categoryIdentifier = "timer.category"
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: Minutes, repeats: false)
let request = UNNotificationRequest(identifier: "timer.request", content: content, trigger: trigger)
UNUserNotificationCenter.current().add(request) { (error) in
if let error = error{
print("Error posting notification:\(error.localizedDescription)")
}
}
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if response.actionIdentifier == "stop.action"{
stopTimer()
}
completionHandler()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert,.sound])
}
//MARK: - UIButtons
@IBAction func slider(_ sender: UISlider)
{
Minutes = Double(sender.value)
label.text = String(format: "%.0f", Minutes) + " Minutes"
}
@IBAction func start(_ sender: AnyObject) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(counter), userInfo: nil, repeats: true)
sliderOutlet.isHidden = true
startOutlet.isHidden = true
self.sendNotification()
}
func counter() {
DispatchQueue.main.async {
self.Minutes -= 1
self.label.text = String(format: "%.0f", self.Minutes) + " Minutes"
}
if (Minutes == 0)
{
timer.invalidate()
sliderOutlet.isHidden = false
startOutlet.isHidden = false
}
}
@IBAction func stop(_ sender: AnyObject)
{
timer.invalidate()
Minutes = 0
sliderOutlet.setValue(10, animated: true)
label.text = "0 Minutes"
audioPlayer.stop()
sliderOutlet.isHidden = false
startOutlet.isHidden = false
}
override func viewDidLoad()
{
super.viewDidLoad()
print(vc.isGrantedAccess)
do
{
let audioPath = Bundle.main.path(forResource: "1", ofType: ".mp3")
try audioPlayer = AVAudioPlayer(contentsOf: URL(fileURLWithPath: audioPath!))
}
catch
{
//ERROR
}
}
进入后台时将 Date() 存储在 NSUserDefaults 中
func applicationDidEnterBackground(_ application: UIApplication) {}
然后在
中进入前台时计算新日期之间的差异func applicationWillEnterForeground(_ application: UIApplication) {}