无需重新排序控制即可重新排序UITableView

Jo *_*Roy 15 cocoa-touch drag-and-drop uitableview ios

我需要用户能够通过这种方式重新排序UITableView:他触摸一个单元格预定的时间段(例如1秒),然后他可以将其拖放到其他单元格上.

我知道如何使用手势识别器实现"长触摸"检测,但是在不使用重新排序控件的情况下实现拖放功能的最佳方法是什么(用户应该从单元格中的任何位置拖动单元格,而不仅仅是重新排序控制)?

m_k*_*kis 6

这是一个老问题,但这是一个经过测试并使用iOS 811的解决方案.

在你的UITableViewCell子类中试试这个:

class MyTableViewCell: UITableViewCell {
    weak var reorderControl: UIView?

    override func layoutSubviews() {
        super.layoutSubviews()

        // Make the cell's `contentView` as big as the entire cell.
        contentView.frame = bounds

        // Make the reorder control as big as the entire cell 
        // so you can drag from everywhere inside the cell.
        reorderControl?.frame = bounds
    }

    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: false)
        if !editing || reorderControl != nil {
            return
        }

        // Find the reorder control in the cell's subviews.
        for view in subviews {
            let className = String(describing: type(of:view))
            if className == "UITableViewCellReorderControl" {

                // Remove its subviews so that they don't mess up
                // your own content's appearance.
                for subview in view.subviews {
                    subview.removeFromSuperview()
                }

                // Keep a weak reference to it for `layoutSubviews()`.
                reorderControl = view

                break
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它接近Senseful的第一个建议,但他引用的文章似乎不再有效.

你所做的,是使重新排序控制和单元格的内容视图在编辑时与整个单元格一样大.这样,您可以从单元格内的任何位置拖动,并且您的内容会占用整个空间,就好像根本没有编辑单元格一样.

最重要的缺点是,您正在改变系统的单元视图结构并引用私有类(UITableViewCellReorderControl).它似乎适用于所有最新的iOS版本,但您必须确保每次新的操作系统出现时它仍然有效.


ber*_*ium 5

我解决了以下步骤的问题:

  1. 将手势识别器附加到 UITableView。
  2. 通过“长按”检测哪个单元格被点击。此时创建所选单元格的快照,将其放入 UIImageView 并放置在 UITableView 上。UIImageView 的坐标应该相对于 UITableView 计算所选单元格(所选单元格的快照应该覆盖所选单元格)。
  3. 存储所选单元格的索引,删除所选单元格并重新加载 UITableView。
  4. 禁用 UITableView 的滚动。现在您需要在拖动单元格时更改快照 UIImageView 的帧。你可以用touchesMoved方法来做。
  5. 当用户手指离开屏幕时,创建新单元格并重新加载 UITableView(您已经存储了索引)。
  6. 移除快照 UIImageView。

但做到这一点并不容易。