【问题标题】:Reordering sections in UITableView重新排序 UITableView 中的部分
【发布时间】:2018-10-02 11:25:51
【问题描述】:

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

【问题讨论】:

    标签: ios uitableview move sections


    【解决方案1】:

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

    手势应该比较明显。从标题开始后,您需要在表格视图中使用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()
    

    由于您将删除该部分,因此您还将删除具有手势识别器的视图(标题)。这意味着直接将手势添加到表格视图或它的超级视图可能会更好。只有在按下标题上的这些按钮之一时,您才需要强制它触发。你可以对它有所了解here。其余部分不受此更改的影响。

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

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

    所以到目前为止,您应该能够抓取一个折叠所有单元格的部分,并能够拖动“部分堆栈”视图。现在您需要检查您的手指在表格视图中的位置,以了解该部分的放置位置。这有点痛苦,但可以通过visibleCellstableView.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 来获得它的位置。

    玩得开心。

    【讨论】:

    • 哇,如此详细而有用的答案。谢谢你的帮助。我会努力去理解和实现。
    猜你喜欢
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多