Timer设置重复触发却仅调用一次selector的问题求助
问题解决:Timer重复触发仅调用一次Selector的修复方案
你已经通过修复Timer的fireDate相关问题解决了Timer仅触发一次的问题,这里整理了完整的修正后代码和关键细节,供你和其他开发者参考:
核心代码实现
1. 录制按钮初始化
let photoButton: UIButton = { let but = UIButton(type: .custom) but.layer.cornerRadius = 40 but.layer.borderColor = UIColor.white.cgColor but.layer.borderWidth = 4 but.clipsToBounds = true but.addTarget(self, action: #selector(takeVideo), for: .touchDown) but.addTarget(self, action: #selector(stopVideo), for: [.touchUpInside, .touchUpOutside]) but.translatesAutoresizingMaskIntoConstraints = false return but }()
2. 长按开始录制与Timer初始化
@objc func takeVideo() { progressBar.isHidden = false timer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(updateProgressbar), userInfo: nil, repeats: true) startTime = Date().timeIntervalSince1970 timer?.fire() // 立即触发第一次进度更新,避免延迟 }
3. 停止录制与Timer终止
@objc func stopVideo() { timer?.invalidate() // 这里添加停止视频录制的逻辑 }
4. 进度条更新逻辑
@objc private func updateProgressbar() { let maxLength = 7.0 guard let startTime = startTime else { return } let difference = Date().timeIntervalSince1970 - startTime progressBar.progress = Float(difference / maxLength) if difference >= maxLength { stopVideo() // 达到7秒自动停止录制并终止Timer } }
5. 视图控制器异步呈现
let recorder = RecorderViewController() recorder.db = db DispatchQueue.main.async { self.present(recorder, animated: true) }
关键修复要点
- Timer触发逻辑修正:确保使用
Timer.scheduledTimer并设置repeats: true,同时调用timer?.fire()让Timer立即执行一次,避免进度条出现初始延迟。 - 安全的时间差计算:添加
guard let解包startTime,避免可选值为空导致的崩溃。 - 主线程UI操作:视图控制器的呈现放在主队列异步执行,保证所有UI操作都在主线程完成,避免线程冲突问题。
内容的提问来源于stack exchange,提问作者kbunarjo
相关产品推荐
相关产品推荐

