滑动TableView单元格时停止Timer,取消滑动时重启Timer的实现问题
解决TableView滑动取消编辑时重启Timer的问题
这个场景我太熟了!刚好可以借助UITableView的代理方法完美实现需求,下面一步步给你拆解解决方案:
1. 先确保Timer是类级变量
首先把你的Timer定义成ViewController(或TableView所在类)的实例变量,这样能在各个方法里方便操作它:
var updateTimer: Timer?
2. 保留你已有的停止Timer逻辑
在editActionsForRowAt里停止Timer的代码你已经写了,这里可以优化一下,顺便把删除后的Timer重启也加上:
func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? { // 先停止当前的Timer updateTimer?.invalidate() updateTimer = nil let deleteAction = UITableViewRowAction(style: .destructive, title: "删除") { [weak self] (action, indexPath) in // 执行你的删除逻辑 tableView.deleteRows(at: [indexPath], with: .automatic) // 删除完成后重启Timer self?.restartTimer() } return [deleteAction] }
3. 关键:监听编辑状态结束来重启Timer
当用户点击外部(比如TableView空白处、导航栏等)取消单元格滑动编辑时,UITableView会调用didEndEditingRowAt代理方法,我们就在这里重启Timer:
func tableView(_ tableView: UITableView, didEndEditingRowAt indexPath: IndexPath?) { // 不管是取消编辑还是删除完成,只要编辑状态结束就重启Timer restartTimer() }
4. 封装重启Timer的辅助方法
为了避免重复代码,把重启Timer的逻辑封装成私有方法,还能顺便处理RunLoop的问题(防止滑动TableView时Timer暂停):
private func restartTimer() { // 先确保旧Timer已经停止 updateTimer?.invalidate() // 创建并启动新的Timer updateTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in // 这里写你更新TableView可见行的逻辑 self?.updateVisibleTableViewRows() } // 把Timer加入common模式的RunLoop,保证滑动时Timer也能正常执行 if let timer = updateTimer { RunLoop.current.add(timer, forMode: .common) } } // 你的可见行更新方法示例 private func updateVisibleTableViewRows() { guard let visibleIndexPaths = tableView.indexPathsForVisibleRows else { return } for indexPath in visibleIndexPaths { if let cell = tableView.cellForRow(at: indexPath) { // 更新单元格内容的逻辑 cell.textLabel?.text = "更新时间:\(Date())" } } }
5. 别忘了清理Timer避免内存泄漏
在类的销毁方法里停止Timer,防止内存泄漏:
deinit { updateTimer?.invalidate() updateTimer = nil }
这样一来,不管是用户点击删除按钮完成操作,还是点击外部取消滑动编辑,Timer都会及时重启,完美匹配你的需求!
内容的提问来源于stack exchange,提问作者Rijaz Ali
相关产品推荐
相关产品推荐

