I want to be able to reorder tableview cells using a longPress gesture (not with the standard reorder controls). After the longPress is recognized I want the tableView to essent
There's a great Swift library out there now called SwiftReorder that is MIT licensed, so you can use it as a first party solution. The basis of this library is that it uses a UITableView
extension to inject a controller object into any table view that conforms to the TableViewReorderDelegate
:
extension UITableView {
private struct AssociatedKeys {
static var reorderController: UInt8 = 0
}
/// An object that manages drag-and-drop reordering of table view cells.
public var reorder: ReorderController {
if let controller = objc_getAssociatedObject(self, &AssociatedKeys.reorderController) as? ReorderController {
return controller
} else {
let controller = ReorderController(tableView: self)
objc_setAssociatedObject(self, &AssociatedKeys.reorderController, controller, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return controller
}
}
}
And then the delegate looks somewhat like this:
public protocol TableViewReorderDelegate: class {
// A series of delegate methods like this are defined:
func tableView(_ tableView: UITableView, reorderRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath)
}
And the controller looks like this:
public class ReorderController: NSObject {
/// The delegate of the reorder controller.
public weak var delegate: TableViewReorderDelegate?
// ... Other code here, can be found in the open source project
}
The key to the implementation is that there is a "spacer cell" that is inserted into the table view as the snapshot cell is presented at the touch point, so you need to handle the spacer cell in your cellForRow:atIndexPath:
call:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let spacer = tableView.reorder.spacerCell(for: indexPath) {
return spacer
}
// otherwise build and return your regular cells
}