Swift:ViewController手动Dismiss时停止Timer的实现问询
解决Swift中手动dismiss后Timer仍运行的问题
嘿,这个坑我之前踩过!问题出在你现在的Timer是局部变量,而且没有在ViewController被手动dismiss时主动停止它——RunLoop会一直持有这个Timer,直到它完成循环,所以哪怕VC已经被销毁,计时归零的逻辑还是会触发。下面给你修改方案:
第一步:把Timer改成ViewController的实例变量
首先在你的ViewController类里声明一个可选类型的Timer变量,这样我们能在其他方法里访问并控制它:
class YourViewController: UIViewController { var countdownTimer: Timer? // 新增实例变量 var counter = 10 // 假设你的初始计数是10,根据实际情况调整 @IBOutlet weak var timerLabel: UILabel! // 其他代码... }
第二步:初始化Timer并赋值给实例变量
在viewDidLoad里,把原来的局部Timer替换成赋值给实例变量的写法:
override func viewDidLoad() { super.viewDidLoad() // 初始化Timer并保存引用 countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(updateCounter), userInfo: nil, repeats: true) timerLabel.text = "\(counter)" }
第三步:手动dismiss时停止Timer
有两种方式确保手动dismiss时Timer停止:
方式一:在手动调用dismiss的地方主动停止
如果你是通过按钮或其他事件手动触发dismiss,在调用dismiss前先停止Timer:
@IBAction func manualDismissButtonTapped(_ sender: UIButton) { countdownTimer?.invalidate() countdownTimer = nil // 置空避免无效引用 dismiss(animated: true, completion: nil) }
方式二:利用ViewController生命周期方法自动处理
如果不确定手动dismiss的触发点,或者想统一处理所有dismiss场景,可以重写viewWillDisappear方法,判断VC是否正在被dismiss,然后停止Timer:
override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 只有当VC被dismiss时才停止Timer(避免push到其他VC时误停) if isBeingDismissed { countdownTimer?.invalidate() countdownTimer = nil } }
第四步:完善自动dismiss的逻辑
在计时归零自动dismiss的时候,也要记得停止Timer,避免重复触发:
@objc func updateCounter() { if counter >= 0 { timerLabel.text = "\(counter)" counter -= 1 } if counter == -1 { // 这里注意:因为counter在显示后减1,所以当显示0后,counter会变成-1,此时触发dismiss更准确 print("COUNTER GOT TO ZERO") countdownTimer?.invalidate() countdownTimer = nil dismiss(animated: true, completion: nil) } }
小提示:原来的逻辑里,当counter等于0时显示0,然后减1变成-1,但此时会触发dismiss。如果按原来的判断
counter == 0,会在显示0的同时触发dismiss,可能导致UI显示和dismiss不同步,改成判断counter == -1会更合理——等显示完0之后再执行dismiss。
内容的提问来源于stack exchange,提问作者King
相关产品推荐
相关产品推荐

