UITableView重排至屏幕外的Cell动画异常问题求助
问题:NSFetchedResultsController 移动行至屏幕外时无动画,如何实现带动画滑出?
我使用 NSFetchedResultsController 作为 UITableView 的数据源,目前遇到一个动画相关的问题:当重排Cell使其移动到屏幕内或略微超出屏幕的位置时,Cell会带动画平滑移动到新位置;但当Row被移动到完全超出屏幕的新位置时,它会直接“跳”过去,没有任何动画效果。我希望这种场景下Row能带着动画滑出屏幕,请问有没有办法不用实现自定义动画方法就能达成这个需求?
我的 NSFetchedResultsControllerDelegate 中处理 .move 类型的代码如下:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { switch type { case .insert: tableView.insertRows(at: [newIndexPath!], with: UITableViewRowAnimation.none) case .delete: tableView.deleteRows(at: [indexPath!], with: UITableViewRowAnimation.none) case .update: tableView.reloadRows(at: [indexPath!], with: UITableViewRowAnimation.none) case .move: tableView.moveRow(at: indexPath!, to: newIndexPath!) } }
解答
这是 UITableView 配合 NSFetchedResultsController 时的一个默认行为:当移动的目标位置完全处于屏幕可视区域外时,系统会认为用户看不到这个移动过程,因此跳过动画直接完成更新。不过不用写复杂的自定义动画逻辑,我们只需要调整代理中对 .move 类型的处理方式就能解决问题。
你可以把原来的 tableView.moveRow(at:to:) 拆成先删除原位置的行(带上滑出动画),再在新位置插入行(用无动画即可),具体修改后的代码如下:
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { switch type { case .insert: tableView.insertRows(at: [newIndexPath!], with: UITableViewRowAnimation.none) case .delete: tableView.deleteRows(at: [indexPath!], with: UITableViewRowAnimation.none) case .update: tableView.reloadRows(at: [indexPath!], with: UITableViewRowAnimation.none) case .move: // 替换moveRow方法,拆分为删除+插入 tableView.deleteRows(at: [indexPath!], with: .left) // 这里可以选择你想要的滑出动画,比如.left/.right/.fade tableView.insertRows(at: [newIndexPath!], with: .none) // 新位置在屏幕外,插入动画用户不可见,用none不影响体验 } }
原理说明:
- 调用
deleteRows时,UITableView 会对当前屏幕内的行执行你指定的删除动画,这样就能实现行带着动画滑出屏幕的效果,不管目标位置在哪里 - 插入操作因为新位置在屏幕外,用户完全看不到这个过程,所以用无动画既保证了数据源和UI的一致性,又不会造成不必要的性能消耗
注意点:
- 动画类型可以根据你的APP风格调整,
.left、.right、.fade都是UITableView自带的可选动画 - 这种方式完全依赖UITableView的原生API,不需要实现任何自定义动画方法,刚好符合你的需求
内容的提问来源于stack exchange,提问作者alionthego
相关产品推荐
相关产品推荐

