我需要用户能够通过这种方式重新排序UITableView:他触摸一个单元格预定的时间段(例如1秒),然后他可以将其拖放到其他单元格上。
我知道如何使用手势识别器实现“长触摸”检测,但是在不使用重新排序控件的情况下实现拖放功能的最佳方法是什么(用户应该从单元格中的任何位置拖动单元格,不仅来自重新订购控制)?
答案 0 :(得分:6)
这是一个老问题,但这是一个经过测试并使用 iOS 8 到 11 的解决方案。
在你的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
}
}
}
}
它接近Senseful's first suggestion,但他引用的文章似乎不再起作用。
您所做的是使重新排序控件和单元格的内容视图在编辑时与整个单元格一样大。这样,您可以从单元格内的任何位置拖动,并且您的内容会占用整个空间,就像根本没有编辑单元格一样。
最重要的缺点是,您正在改变系统的单元视图结构并引用私有类( UITableViewCellReorderControl )。它似乎适用于所有最新的iOS版本,但您必须确保每次新的操作系统出现时它仍然有效。
答案 1 :(得分:4)
我解决了以下步骤的问题:
touchesMoved
方法。但要做到这一点并不容易。
答案 2 :(得分:2)
供将来参考...... 我遇到了同样的问题,我发现了另一个问题(Swift - Drag And Drop TableViewCell with Long Gesture Recognizer)并且有人建议了这个教程:https://www.freshconsulting.com/create-drag-and-drop-uitableview-swift/ 对我来说非常合适
答案 3 :(得分:1)
文章Reordering a UITableViewCell from any touch point讨论了这个确切的场景。
基本上,您可以执行以下操作:
UITableViewCellReorderControl
(私人课程)。另一个解决方案Cookbook: Moving Table View Cells with a Long Press Gesture通过执行以下操作实现了相同的效果:
-[UITableView moveRowAtIndexPath:toIndexPath:]
。答案 4 :(得分:0)
我知道这是关于UITableView的问题。但最后我提出了使用UICollectionView而不是UITableView来实现longtap重排序的解决方案。简单,简单。
答案 5 :(得分:0)
tableView.dragInteractionEnabled = true
tableView.dragDelegate = self
tableView.dropDelegate = self
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { }
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession,
at: indexPath: IndexPath) -> [UIDragItem] {
return [UIDragItem(itemProvider: NSItemProvider())]
}
func tableView(_ tableView: UITableView, dropSessionDidUpdate session:
UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
if session.localDragSession != nil {
return UITableViewDropProposal(operation: .move, intent: .insertAtDestinationIndexPath)
}
return UITableViewDropProposal(operation: .cancel, intent: .unspecified)
}
func tableView(_ tableView: UITableView, performDropWith coordinator: UITableViewDropCoordinator) {
}