做 iOS 列表优化最头疼的就是快速滑动时图片疯狂加载、导致卡顿掉帧。今天直接给你一个生产环境能用、简单粗暴、零坑的方案UITableView 滑动时暂停所有图片下载停止滑动后只加载当前可见 cell 的图片。基于 Kingfisher纯手写复制就能跑。一、核心思路一句话讲清监听列表滚动状态开始滑动 暂停图片下载停止滑动 恢复下载 刷新可见 cellcell 复用的时候取消旧图片请求防止错乱全程不影响滑动流畅度不浪费流量二、完整代码直接复制使用1. 控制器代码核心逻辑import UIKit import Kingfisher class SmoothListController: UIViewController { IBOutlet weak var tableView: UITableView! // 你的数据源 var dataList: [YourModel] [] // 标记是否正在滑动 private var isScrolling false override func viewDidLoad() { super.viewDidLoad() setupTableView() } private func setupTableView() { tableView.delegate self tableView.dataSource self tableView.register(ImageCell.self, forCellReuseIdentifier: ImageCell) } } // MARK: - 滚动代理控制图片加载 extension SmoothListController: UIScrollViewDelegate { /// 开始拖动手指按住滑动 func scrollViewWillBeginDragging(_ scrollView: UIScrollView) { isScrolling true // 滑动瞬间暂停所有图片下载 KingfisherManager.shared.downloader.pauseAll() } /// 结束拖动手指松开没有减速 func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { if !decelerate { loadVisibleCellImages() } } /// 滚动完全停止减速结束 func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { loadVisibleCellImages() } /// 恢复加载只刷新当前屏幕可见的 cell private func loadVisibleCellImages() { isScrolling false KingfisherManager.shared.downloader.resumeAll() // 局部刷新不 reload 整个表格 guard let visibleRows tableView.indexPathsForVisibleRows else { return } tableView.reloadRows(at: visibleRows, with: .none) } } // MARK: - 列表数据源 extension SmoothListController: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) - Int { dataList.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) - UITableViewCell { let cell tableView.dequeueReusableCell(withIdentifier: ImageCell, for: indexPath) as! ImageCell let model dataList[indexPath.row] cell.titleLabel.text model.title // 关键只有停止滑动才加载图片 if !isScrolling { cell.iconView.kf.setImage(with: URL(string: model.imageUrl)) } else { cell.iconView.image nil // 滑动中清空防止闪烁 } return cell } }2. 自定义 Cell防止图片错乱class ImageCell: UITableViewCell { let iconView UIImageView() let titleLabel UILabel() override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) // 你自己布局这里省略 } required init?(coder: NSCoder) { fatalError(init(coder:) has not been implemented) } // 复用 cell 时必须取消旧请求 override func prepareForReuse() { super.prepareForReuse() iconView.kf.cancelDownloadTask() iconView.image nil } }3. 数据模型自己替换struct YourModel { let title: String let imageUrl: String }三、关键细节写项目必看为什么用 pauseAll /resumeAll滑动时直接暂停所有下载完全不占用主线程滑动绝对丝滑。为什么只刷新可见 cellreloadData会卡reloadRows(at: visibleRows)只刷新屏幕里的性能拉满。cell 复用必须 cancel 任务不复用、不取消图片百分百错乱。滑动时清空 image防止快速滑动时旧图片闪一下再替换体验干净。覆盖所有停止场景手指松开就停、松开后减速两种场景都处理到位。四、效果总结快速滑动列表不加载任何图片丝滑不卡顿停止滑动瞬间加载当前屏幕图片滑出屏幕的 cell不加载省流量、省内存这是我做列表优化必用的一段代码简单、稳定、没坑。你直接把数据模型换成自己的布局改改就能上线。