You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift初学者求助:如何实现带条件的定时器控制器更新Bottom Sheet文案

实现应用后台三分钟后更新Bottom Sheet状态的正确方案

现有代码的问题

  • 变量waktu未被任何逻辑更新,永远无法满足waktu == 180的条件,状态修改逻辑永远不会触发
  • 未持有定时器的引用,timer变量未定义,调用invalidate()会直接报错
  • 未考虑应用前后台状态切换:如果用户在三分钟内切回应用,现有代码仍会在计时结束后修改状态,不符合需求

正确实现思路

要实现「应用进程三分钟未运行(即处于后台状态达三分钟)」时修改Bottom Sheet消息,核心是监听应用的前后台状态,并在对应时机启动/销毁定时器:

  1. 监听UIApplication.didEnterBackgroundNotification(应用进入后台)和UIApplication.willEnterForegroundNotification(应用即将进入前台)通知
  2. 应用进入后台时启动3分钟一次性定时器,计时结束后修改状态
  3. 应用进入前台时立即销毁定时器,并恢复Bottom Sheet的"available"状态
  4. 持有定时器的可选引用,方便随时管理其生命周期

完整代码示例

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 23:15:21