Swift 5中TableView开启isPagingEnabled无法滚动到完整高度下一个cell如何解决
问题原因
UITableView 继承自 UIScrollView,系统自带的 isPagingEnabled = true 逻辑是按ScrollView自身的frame高度进行分页,而非按cell高度分页。你的cell固定高度为755,只要该高度和TableView的实际frame高度不一致,就会出现滚动后cell显示不全的问题。
解决方案
要实现类似TikTok的逐cell完整滚动效果,推荐两种适配方案:
方案1:手动控制滚动停止位置(适配固定cell高度场景)
关闭系统自带分页,通过UIScrollView代理方法手动控制滚动到完整cell位置,步骤如下:
- 定义全局统一的cell高度、cell总数常量,保持所有相关场景取值一致
- 关闭系统分页,设置滚动减速速率优化手感
- 实现
scrollViewWillEndDragging代理方法,手动计算目标cell位置并滚动
修改后的完整代码如下:
import UIKit private let id = "ss" private let cellHeight: CGFloat = 755 // 统一cell高度 private let totalCellCount = 16 // 统一cell总数 class TableView:UITableViewController { override func viewDidLoad() { super.viewDidLoad() tableView.register(UITableViewCell.self, forCellReuseIdentifier: id) // 关闭系统自带分页 tableView.isPagingEnabled = false // 设置更快的减速速率,接近TikTok滚动手感 tableView.decelerationRate = .fast } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return totalCellCount } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: id, for: indexPath) cell.backgroundColor = .red return cell } override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return cellHeight } // 核心滚动控制逻辑 override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { // 取消系统默认的滚动目标位置 targetContentOffset.pointee = scrollView.contentOffset // 计算当前滚动位置对应的目标cell索引 var targetIndex = round(scrollView.contentOffset.y / cellHeight) // 适配快速滑动场景,根据滑动速度调整目标索引 if velocity.y > 0 { targetIndex += 1 } else if velocity.y < 0 { targetIndex -= 1 } // 处理边界,避免索引越界 let finalIndex = max(0, min(Int(targetIndex), totalCellCount - 1)) // 滚动到目标cell顶部 tableView.scrollToRow(at: IndexPath(row: finalIndex, section: 0), at: .top, animated: true) } }
方案2:cell高度适配TableView高度(适配全屏cell场景,实现更简单)
如果你的需求就是每个cell占满全屏,直接将cell高度设置为和TableView的frame高度一致,此时系统自带的isPagingEnabled就可以直接正常工作,无需写额外代理逻辑,适配不同屏幕尺寸的兼容性也更好。
仅需要修改两处代码即可:
- 保持
tableView.isPagingEnabled = true配置不变 - 将
heightForRowAt的返回值修改为tableView.bounds.height
内容的提问来源于stack exchange,提问作者ayoub
相关产品推荐
相关产品推荐

