如何阻止 UITableview 一次滚动多个单元格

Posted

技术标签:

【中文标题】如何阻止 UITableview 一次滚动多个单元格【英文标题】:How do I stop UITableview from scrolling more than one cell at a time 【发布时间】:2020-09-29 21:45:18 【问题描述】:

所以我的每个 tableview 单元格都是全屏高度,类似于 tiktok、igtv 等。当用户滚动时,我希望 tableview 在每个单元格处停止,不能滚动一次并超过 2/3 个单元格。

我正在以编程方式使用自定义 tableview 单元,这就是我当前实现 tableview 委托和数据源功能的方式

 override func viewDidLoad() 
     super.viewDidLoad()
    tableView.register(PostViewTableCell.self, forCellReuseIdentifier: PostViewTableCell.cellReuseIdentifier)
    tableView.allowsSelection = false
    tableView.bounces = false


override var prefersStatusBarHidden: Bool 
    return true


override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    return viewModel?.postInformations.count ?? 0


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    guard let cell = tableView.dequeueReusableCell(withIdentifier: PostViewTableCell.cellReuseIdentifier) as? PostViewTableCell else 
        fatalError("Couldn't dequeue reusable cell")
    
    cell.postViewCellOutput = self
    cell.setUpCell(position: indexPath.row, viewModel: viewModel)
    
 
    return cell


override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    return tableView.frame.size.height

所以我在单元格上调用 canPlay 以播放在屏幕上完全可见的单元格,以便它可以开始播放。我正在使用这种方法来检查可见性:

private func checkIfCellIsVisible(indexPath: IndexPath) -> Bool 
    let cellRect = tableView.rectForRow(at: indexPath)
    return tableView.bounds.contains(cellRect)

【问题讨论】:

这能回答你的问题吗? swift 3 ios tableview scroll by cell 不,我检查了那个问题,他们没有解决方案 您尝试接受的答案了吗?它看起来确实不错(虽然我没有尝试) 不行 【参考方案1】:

您可以在 UITableViewDelegate 上使用 UIScrollViewDelegate 的 func scrollViewWillEndDragging(_:withVelocity:targetContentOffset:),因为它也是一个滚动视图委托来检测拖动结束并将 targetContentOffset 设置为您想要的行,在这种情况下为下一行。例如:

var currIndexPath = IndexPath(row: 1, section: 0)

func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) 
    let rect = tableview.rectForRow(at: self.currentIndexPath)
    targetContentOffset.pointee = CGPoint(x: rect.minX, y: rect.minY)
    self.currentIndexPath = IndexPath(row: self.currentIndexPath.row+1, section: 0)

这里的好处是你的行的高度是全屏的,因此可以确保拖动在当前显示的行中结束。如果行高不是全屏,这将无法正常工作,因为您会看到滚动经过几个单元格,但最终会转到您想要的单元格。

【讨论】:

这不起作用,它仍然允许我滚动一次,它会继续滚动过一个单元格。 它只在用户登陆控制器时工作一次。当我滚动回上面的项目时,它不起作用。【参考方案2】:

感谢您的回复。这是我解决它的方法。我设置:

  tableView.isScrollEnabled = false // Set the tableview scroll enabled to false

然后在“cellForRowAt indexPath:IndexPath”函数中,我将第一行的 indexPath 保存到 currentIndexPath 属性中:

  currentIndexPath = indexPath

然后我在表格视图中添加了一个手势识别器用于向上滑动:

   let swipeToNextVideoGesture = UISwipeGestureRecognizer(target: self, action: 
    #selector(swipeToNext(_:)))
    swipeToNextVideoGesture.direction = .up
    tableView.addGestureRecognizer(swipeToNextVideoGesture)

然后在函数中我首先检查下一行是否在 tableview 数据源数组边界中,然后我滚动到该行:

    @objc private func swipeToNext(_ gesture: UISwipeGestureRecognizer) 
    let nextVideoIndexPath = currentIndexPath.row+1
    if !(nextVideoIndexPath >= viewModel.postInformations.count) 
        currentIndexPath = IndexPath(row: nextVideoIndexPath, section: indexPathSection)
        tableView.scrollToRow(at: currentIndexPath, at: .none, animated: true)
    

【讨论】:

以上是关于如何阻止 UITableview 一次滚动多个单元格的主要内容,如果未能解决你的问题,请参考以下文章

iPhone:滚动 UITableView 多达 60 多个自定义单元格时应用程序崩溃

如何阻止 UITableView 单元格在视图更改时消失

滚动后 UITableView 单元格正确

滚动时如何使uitableview单元格不改变?

Swift中带有标题的TableView的自定义分页大小(一次滚动一个单元格)

如何逐个单元格地自动滚动 UITableView