Swift初学者求助:如何实现带条件的定时器控制器更新Bottom Sheet文案
实现应用后台三分钟后更新Bottom Sheet状态的正确方案
现有代码的问题
- 变量
waktu未被任何逻辑更新,永远无法满足waktu == 180的条件,状态修改逻辑永远不会触发 - 未持有定时器的引用,
timer变量未定义,调用invalidate()会直接报错 - 未考虑应用前后台状态切换:如果用户在三分钟内切回应用,现有代码仍会在计时结束后修改状态,不符合需求
正确实现思路
要实现「应用进程三分钟未运行(即处于后台状态达三分钟)」时修改Bottom Sheet消息,核心是监听应用的前后台状态,并在对应时机启动/销毁定时器:
- 监听
UIApplication.didEnterBackgroundNotification(应用进入后台)和UIApplication.willEnterForegroundNotification(应用即将进入前台)通知 - 应用进入后台时启动3分钟一次性定时器,计时结束后修改状态
- 应用进入前台时立即销毁定时器,并恢复Bottom Sheet的"available"状态
- 持有定时器的可选引用,方便随时管理其生命周期
完整代码示例
import UIKit class YourViewController: UIViewController { // 持有定时器引用,用于后续销毁 private var inactivityTimer: Timer? // 假设你有一个用于显示Bottom Sheet消息的UILabel @IBOutlet weak var bottomSheetMessageLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() // 初始化Bottom Sheet状态为"available" bottomSheetMessageLabel.text = "available" // 注册应用前后台状态监听通知 setupAppStateNotifications() } private func setupAppStateNotifications() { NotificationCenter.default.addObserver( self, selector: #selector(onAppEnteredBackground), name: UIApplication.didEnterBackgroundNotification, object: nil ) NotificationCenter.default.addObserver( self, selector: #selector(onAppEnteredForeground), name: UIApplication.willEnterForegroundNotification, object: nil ) } @objc private func onAppEnteredBackground() { // 应用进入后台,启动3分钟定时器 inactivityTimer = Timer.scheduledTimer(withTimeInterval: 180.0, repeats: false) { [weak self] _ in self?.updateBottomSheetStatus(to: "not available") } } @objc private func onAppEnteredForeground() { // 应用回到前台,销毁定时器并恢复状态 inactivityTimer?.invalidate() inactivityTimer = nil updateBottomSheetStatus(to: "available") } private func updateBottomSheetStatus(to status: String) { // UI操作必须在主线程执行 DispatchQueue.main.async { self.bottomSheetMessageLabel.text = status } } deinit { // 页面销毁时移除通知监听,避免内存泄漏 NotificationCenter.default.removeObserver(self) // 销毁定时器 inactivityTimer?.invalidate() } }
关键细节说明
- 使用
[weak self]捕获self,避免定时器与ViewController形成循环引用导致内存泄漏 - 所有UI更新逻辑必须包裹在
DispatchQueue.main.async中,确保在主线程执行 - 在
deinit方法中移除通知监听并销毁定时器,保证资源被正确释放 - 应用回到前台时立即重置状态,确保用户看到的是最新的可用状态
内容的提问来源于stack exchange,提问作者Bima J Hermid
相关产品推荐
相关产品推荐

