求助: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
相关产品推荐
相关产品推荐

