栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在后台快速NSTimer

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在后台快速NSTimer

您不应该根据进入后台或恢复的时间来进行任何调整,而只需节省您要数的时间(取决于您是在递增还是递减)。然后,当应用再次启动时,您只需在重构计时器时使用该时间即可。

同样,请确保您的计时器处理程序不依赖于调用处理选择器的确切时间(例如, 不要
执行

seconds++
任何类似操作,因为您可能希望调用时不会准确地调用它),但请务必返回从/到时间。


这是一个倒数计时器的示例,它说明我们不对任何东西进行“计数”。我们也不在乎介于

appDidEnterBackground
和之间的时间
appDidBecomeActive
。只需保存停止时间,然后计时器处理程序就可以将目标
stopTime
时间与当前时间进行比较,并根据需要显示经过的时间。

例如:

import UIKitimport UserNotificationsprivate let stopTimeKey = "stopTimeKey"class ViewController: UIViewController {    @IBOutlet weak var datePicker: UIDatePicker!    @IBOutlet weak var timerLabel: UILabel!    private weak var timer: Timer?    private var stopTime: Date?    let dateComponentsFormatter: DateComponentsFormatter = {        let formatter = DateComponentsFormatter()        formatter.allowedUnits = [.hour, .minute, .second]        formatter.unitsStyle = .positional        formatter.zeroFormattingBehavior = .pad        return formatter    }()    override func viewDidLoad() {        super.viewDidLoad()        registerForLocalNotifications()        stopTime = UserDefaults.standard.object(forKey: stopTimeKey) as? Date        if let time = stopTime { if time > Date() {     startTimer(time, includeNotification: false) } else {     notifyTimerCompleted() }        }    }    @IBAction func didTapStartButton(_ sender: Any) {        let time = datePicker.date        if time > Date() { startTimer(time)        } else { timerLabel.text = "timer date must be in future"        }    }}// MARK: Timer stuffprivate extension ViewController {    func registerForLocalNotifications() {        if #available(iOS 10, *) { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in     guard granted, error == nil else {         // display error         print(error ?? "Unknown error")         return     } }        } else { let types: UIUserNotificationType = [.alert, .sound, .badge] let settings = UIUserNotificationSettings(types: types, categories: nil) UIApplication.shared.registerUserNotificationSettings(settings)        }    }    func startTimer(_ stopTime: Date, includeNotification: Bool = true) {        // save `stopTime` in case app is terminated        UserDefaults.standard.set(stopTime, forKey: stopTimeKey)        self.stopTime = stopTime        // start Timer        timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(handleTimer(_:)), userInfo: nil, repeats: true)        guard includeNotification else { return }        // start local notification (so we're notified if timer expires while app is not running)        if #available(iOS 10, *) { let content = UNMutableNotificationContent() content.title = "Timer expired" content.body = "Whoo, hoo!" let trigger = UNTimeIntervalNotificationTrigger(timeInterval: stopTime.timeIntervalSinceNow, repeats: false) let notification = UNNotificationRequest(identifier: "timer", content: content, trigger: trigger) UNUserNotificationCenter.current().add(notification)        } else { let notification = UILocalNotification() notification.fireDate = stopTime notification.alertBody = "Timer finished!" UIApplication.shared.scheduleLocalNotification(notification)        }    }    func stopTimer() {        timer?.invalidate()    }    // I'm going to use `DateComponentsFormatter` to update the    // label. Update it any way you want, but the key is that    // we're just using the scheduled stop time and the current    // time, but we're not counting anything. If you don't want to    // use `DateComponentsFormatter`, I'd suggest considering    // `Calendar` method `dateComponents(_:from:to:)` to    // get the number of hours, minutes, seconds, etc. between two    // dates.    @objc func handleTimer(_ timer: Timer) {        let now = Date()        if stopTime! > now { timerLabel.text = dateComponentsFormatter.string(from: now, to: stopTime!)        } else { stopTimer() notifyTimerCompleted()        }    }    func notifyTimerCompleted() {        timerLabel.text = "Timer done!"    }}

顺便说一句,以上内容还说明了本地通知的使用(以防定时器在应用当前未运行时到期)。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/484507.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号