Swift tableView分页total_count固定时页码异常递增问题修复
问题根因
页码持续递增是代码逻辑存在多处错误导致的:
- 核心计算逻辑错误:
refresh()里使用+=累加赋值,每次触发都会在现有页码值上额外加固定偏移,而非基于规则计算合法页码;同时错误地把总页数计算结果直接累加到当前页码上,完全不符合分页加载逻辑。当total_count=3时,Int((3-1)/5)=0,每次触发refresh就会执行currentPageNumberVM += 1+0,也就是页码固定每次+1,自然会无限增长。 - 运算符优先级错误:
self.paginationData?.result?.total_count ?? 0 - 1实际执行逻辑是self.paginationData?.result?.total_count ?? (0 - 1),total_count为nil时会取-1,和预期的(total_count ?? 0) -1逻辑不符。 - 缺少加载拦截:
isLoadingList标记赋值为true后,没有在触发加载时做校验,会导致请求未完成时重复触发加载逻辑。 - 分页逻辑混淆:你定义的「每5条一页」是总页数计算规则,不是上拉加载的页码累加规则——上拉加载下一页只需要在当前已加载页码基础上+1,同时判断不超过总页数即可,不需要每次用总条数计算累加值。
符合要求的分页规则
先明确两个固定计算逻辑,完全匹配你提出的规则:
- 总页数计算:
totalPages = (total_count + 5 - 1) / 5(整数除法,等价于向上取整ceil(total_count/5))- total_count为0~5时,totalPages=1
- total_count为6~10时,totalPages=2
- total_count为50时,totalPages=10
- 加载规则:下拉刷新时重置页码为1重新拉取;上拉加载时,当前页码小于总页数则页码+1请求下一页,等于总页数时提示无更多数据,不再发起请求。
修复后的完整代码
var currentPageNumberVM: Int = 1 var isLoadingList: Bool = false // 新增总页数缓存 var totalPages: Int = 1 override func viewDidLoad() { super.viewDidLoad() self.currentPageNumberVM = 1 self.loadMatchesList(page: currentPageNumberVM) } private var paginationData = PaginationMaches(dictionary: NSDictionary()) // 修正方法名命名规范 func loadMatchesList(_ pageNumber: Int) { // 拦截重复请求 guard !isLoadingList else { return } isLoadingList = true let param = ["slug": slugVal ?? "", "page_no": pageNumber] as [String: Any] APIReqeustManager.sharedInstance.serviceCall( param: param, method: .post, url: CommonUrl.get_matches ) { [weak self] resp in guard let self = self else { return } let respModel = PaginationMaches(dictionary: resp.dict as NSDictionary? ?? NSDictionary()) let totalCount = respModel?.result?.total_count ?? 0 // 接口返回后第一时间计算总页数 self.totalPages = (totalCount + 5 - 1) / 5 if pageNumber > 1 { let newMatches = respModel?.result?.matches ?? [Matches]() if newMatches.count > 0 { self.paginationData?.result?.matches! += newMatches } else { // 兜底回退页码,避免接口异常导致页码跳错 self.currentPageNumberVM = max(1, pageNumber - 1) self.showSingleButtonAlertWithoutAction(title: "NO more data to show") } } else { self.paginationData = respModel } self.isLoadingList = false self.machesTable.reloadData() } } @objc func pullToRefresh() { // 下拉刷新逻辑:重置页码为1,重新加载第一页 currentPageNumberVM = 1 loadMatchesList(currentPageNumberVM) } // 上拉加载下一页独立方法 func loadNextPage() { // 正在加载中直接返回 guard !isLoadingList else { return } // 已经到最后一页,直接提示无更多数据 guard currentPageNumberVM < totalPages else { showSingleButtonAlertWithoutAction(title: "NO more data to show") return } // 页码+1加载下一页 currentPageNumberVM += 1 loadMatchesList(currentPageNumberVM) } extension MatchesVC { func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { // 滚动到距底部100pt时触发预加载,阈值可按需调整 let triggerThreshold = scrollView.contentSize.height - scrollView.frame.size.height - 100 if scrollView.contentOffset.y >= triggerThreshold { self.loadNextPage() } } }
关键修复说明
- 移除了原代码中错误的累加计算逻辑,当total_count=3时总页数计算为1,上拉时会直接提示无更多数据,不会再递增页码
- 修复了空值合并运算符的优先级问题,总页数用整数计算实现,避免浮点转换的精度误差
- 补全了加载状态拦截,所有请求发起前先判断是否正在加载,从根源避免重复请求
- 明确区分下拉刷新和上拉加载逻辑,两种操作互不干扰,不会出现页码混乱问题
- 增加了接口异常兜底逻辑,避免接口返回空数据时页码错误跳转
内容的提问来源于stack exchange,提问作者Swift
相关产品推荐
相关产品推荐

