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

求助:UITableView滑动删除时UIActivityIndicator无法正常工作

问题分析与解决方案

嘿,我一眼就瞅出你代码里的两个关键问题,直接导致UIActivityIndicator没法正常工作:

1. 获取Cell的方式完全错了

你调用self.tableView(tableView, cellForRowAt: indexPath)来拿cell,这可是数据源提供新cell的方法啊!它返回的要么是新创建的cell,要么是复用池里的闲置cell,根本不是当前屏幕上用户正在看到的那个cell!你启动的动画是在一个看不见的cell上,自然啥效果都没有。

正确的姿势是用tableView.cellForRow(at: indexPath),这个方法才会返回当前屏幕上对应indexPath的已显示cell实例。

2. GCD嵌套引发的死锁风险

你在managedObjectContext.performAndWait里又套了个DispatchQueue.main.sync,这很容易搞出死锁:performAndWait会同步阻塞当前线程,而main.sync会等主线程空闲,要是当前线程刚好是主线程,直接就卡死了。而且停止动画只需要确保在主线程执行,完全没必要嵌套这么复杂。


修正后的代码

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    if editingStyle == .delete { 
        // 获取当前屏幕上的目标cell,而非新实例
        guard let cell = tableView.cellForRow(at: indexPath),
              let indicator = cell.viewWithTag(136) as? UIActivityIndicatorView else {
            return
        }
        
        indicator.startAnimating() 
        let user = fetchedResultsController.object(at: indexPath) as! SharableUser 
        
        deletee(user: user) { 
            // 用async在主线程停止动画,避免死锁
            DispatchQueue.main.async {
                indicator.stopAnimating()
            }
            
            // Core Data操作放在perform里更安全,不管当前是不是主线程
            self.managedObjectContext.perform {
                user.accept = 0 
                self.saveData(inContext: self.managedObjectContext)
            }
        } 
    } 
}

额外小建议

  • 尽量别用tag找子视图,最好给自定义Cell类加个@IBOutlet weak var loadingIndicator: UIActivityIndicatorView!属性,这样既安全又好维护。
  • 如果网络请求耗时久,建议动画期间禁用该cell的交互,防止用户重复操作。

内容的提问来源于stack exchange,提问作者Mohamed Wasiq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:08:19