重新排列UITableView中的部分

班迪留克

我有带有部分和行的UITableView(https://imgur.com/a/hrYTEVR)。我知道如何启用行的重新排序,但我不知道如何实现节的重新排序。我需要在部分中添加重新排序控件(https://imgur.com/a/V5kU9Ew),然后当用户触摸此控件时,该部分下的行会失败。之后,用户可以将部分移到新位置。在阅读了关于stackoverflow和其他站点的主题之后,我没有发现如何实现这样的好主意。我考虑过通过单元实现节,但是在这种情况下,我无法在节下翻转行以进一步移动到新位置。如果您有任何想法,请给我建议。谢谢!

Matic Oblak

没有本机功能可以实现您想要的。如果我理解正确,那么您将希望折叠整个行的一部分,然后开始拖动“标题”。如果您想自己执行此操作,建议您从平移手势识别器开始,该识别器在标题按钮上触发。

手势应该相对明显。在标题上启动后,您需要locationIn在表格视图中使用来跟踪位置

要折叠行,您需要做的就是使用适当的动画修改表格视图单元格,例如:

tableView.beginUpdates()
tableView.deleteSections([myIndexPath], with: .top) // Maybe experiment with animation type
// Modify whatever you need to correspond this change in the data source
tableView.endUpdates()

由于您将要删除该部分,因此您还将要删除具有手势识别器的视图(标题)。这意味着将手势直接添加到表视图甚至是其超级视图可能会更好。您仅在按下标题上的那些按钮之一时才需要强制它触发。您可以在这里获得一些想法其余不受此更改的影响。

在这一点上,您可能需要创建一个额外的视图,该视图代表您的部分堆栈并跟随您的手指。如果您将其添加为子视图并在其父视图中使用平移手势识别器操纵它的中心,这应该非常容易locationIn

movableSectionView.center = panGestureRecognizer.location(in: movableSectionView.superview!) 

因此,到目前为止,您应该能够抓取一个折叠所有单元格的区域,并能够拖动“部分堆栈”视图。现在,您需要检查表格视图中的哪个位置,以便知道将该部分放在哪里。这有点痛苦,但是可以使用visibleCellsand来完成tableView.indexPath(for: )

func indexPathForGestureRecognizer(_ recognizer: UIGestureRecognizer) -> IndexPath {
    let coordinateView: UIView = tableView.superview! // This can actually be pretty much anything as long as it is in hierarchy
    let y = recognizer.location(in: coordinateView).y
    if let hitCell = tableView.visibleCells.first(where: { cell in
        let frameInCoordinateView = cell.convert(cell.bounds, to: coordinateView)
        return frameInCoordinateView.minY >= y && frameInCoordinateView.maxY <= y
    }) {
        // We have the cell at which the finger is. Retrieve the index path
        return tableView.indexPath(for: hitCell) ?? IndexPath(row: 0, section: 0) // This should always succeed but just in case
    } else {
        // We may be out of bounds. That may be either too high which means above the table view otherwise too low
        if recognizer.location(in: tableView).y < 0.0 {
            return IndexPath(row: 0, section: 0)
        } else {
            guard tableView.numberOfSections > 0 else {
                return IndexPath(row: 0, section: 0) // Nothing in the table view at all
            }
            let section = tableView.numberOfSections-1
            return IndexPath(row: tableView.numberOfRows(inSection: section), section: section)
        }
    }
}

手势识别器结束后,您可以使用此方法获取要放入项目的部分。所以就:

tableView.beginUpdates()
// Modify whatever you need to correspond this change in the data source
tableView.insertSections([indexPathForGestureRecognizer(panGestureRecognizer).section], with: .bottom)
tableView.endUpdates()

基本上,这足以重新排序,但您可能希望在表格视图中显示拖动部分所在的位置。就像在要放入堆栈的部分的末尾有一个占位符。只需添加然后移动一个额外的占位符单元以重新indexPathForGestureRecognizer获得位置,这应该相对容易

玩得开心。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章