How to swap two cells of two different tables view? - ios

I'm stuck with this problem:
I'm using this code to swap two cells of the same table view. I want to ask you how I should edit this code to swap two cells of two different table view in the same controller? I think that there isn't much to edit but I can't do on my own... thank you all.
#objc func onLongPressGestureDone(sender: UILongPressGestureRecognizer) {
let locationInView = sender.location(in: tableViewDone)
let indexPath = tableViewDone.indexPathForRow(at: locationInView)
if sender.state == .began {
if indexPath != nil {
initialIndexPathDone = indexPath
let cell = tableViewDone.cellForRow(at: indexPath!)
cellSnapshotDone = snapshotOfCellDone(inputView: cell!)
var center = cell?.center
cellSnapshotDone?.center = center!
cellSnapshotDone?.alpha = 0.0
tableViewDone.addSubview(cellSnapshotDone!)
UIView.animate(withDuration: 0.25, animations: { () -> Void in
center?.y = locationInView.y
self.cellSnapshotDone?.center = center!
self.cellSnapshotDone?.transform = (self.cellSnapshotDone?.transform.scaledBy(x: 1.05, y: 1.05))!
self.cellSnapshotDone?.alpha = 0.99
cell?.alpha = 0.0
}, completion: { (finished) -> Void in
if finished {
cell?.isHidden = true
}
})
}
} else if sender.state == .changed {
var center = cellSnapshotDone?.center
center?.y = locationInView.y
cellSnapshotDone?.center = center!
if ((indexPath != nil) && (indexPath != initialIndexPathDone)) {
progetto.done.swapAt(indexPath!.row, initialIndexPathDone!.row)
tableViewDone.moveRow(at: initialIndexPathDone!, to: indexPath!)
initialIndexPathDone = indexPath
}
} else if sender.state == .ended {
let cell = tableViewDone.cellForRow(at: initialIndexPathDone!)
cell?.isHidden = false
cell?.alpha = 0.0
UIView.animate(withDuration: 0.25, animations: { () -> Void in
self.cellSnapshotDone?.center = (cell?.center)!
self.cellSnapshotDone?.transform = CGAffineTransform.identity
self.cellSnapshotDone?.alpha = 0.0
cell?.alpha = 1.0
}, completion: { (finished) -> Void in
if finished {
self.initialIndexPathDone = nil
self.cellSnapshotDone?.removeFromSuperview()
self.cellSnapshotDone = nil
}
})
}
}
func snapshotOfCellDone(inputView: UIView) -> UIView {
UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0.0)
inputView.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let cellSnapshotDone = UIImageView(image: image)
cellSnapshotDone.layer.masksToBounds = false
cellSnapshotDone.layer.cornerRadius = 0.0
cellSnapshotDone.layer.shadowOffset = CGSize(width: -5.0, height: 0.0)
cellSnapshotDone.layer.shadowRadius = 5.0
cellSnapshotDone.layer.shadowOpacity = 0.4
return cellSnapshotDone
}

You can do this easier with the moveRow(at:to:) function:
tableView.beginUpdates()
tableView.moveRow(at: firstIndexPath, to: secondIndexPath)
tableView.moveRow(at: secondIndexPath, to: firstIndexPath)
tableView.endUpdates()

Related

UITableView cells animation on scroll. Swift

Community, please help out a beginner! Can you tell me how to make such animation for TableView cells?
Thank!
cell animation as in this video with Swift
This gives something similar to what you want. You might need to make adjustments to it or improve the code snippet.
You can work with the panGestureRecognizer property of the tableView
tableView.panGestureRecognizer.addTarget(self, action: #selector(didPan(_:)))
With this handler:
#objc func didPan(_ gesture: UIPanGestureRecognizer) {
guard gesture.state == .changed else { return }
let loc = gesture.location(in: tableView)
guard let touchedCellIndex = tableView.indexPathForRow(at: loc) else { return }
let n = tableView.numberOfRows(inSection: 0)
guard touchedCellIndex.row < n - 1 else { return }
if gesture.translation(in: tableView).y < 0 {
for (index, cell) in tableView.visibleCells.enumerated() {
guard let ip = tableView.indexPath(for: cell) else { return }
if ip.row > touchedCellIndex.row {
cell.transform = CGAffineTransform(translationX: 0.0, y: -gesture.velocity(in: tableView).y * 0.02 * tanh(CGFloat(index)))
UIView.animate(withDuration: 0.05 * Double(index), delay: 0.0) {
cell.transform = CGAffineTransform.identity
}
}
}
} else {
for (index, cell) in tableView.visibleCells.reversed().enumerated() {
guard let ip = tableView.indexPath(for: cell) else { return }
if ip.row < touchedCellIndex.row {
cell.transform = CGAffineTransform(translationX: 0.0, y: -gesture.velocity(in: tableView).y * 0.02 * tanh(CGFloat(index)))
UIView.animate(withDuration: 0.05 * Double(index), delay: 0.0) {
cell.transform = CGAffineTransform.identity
}
}
}
}
}
I am sure you can optimize this approach and make it more concise.

Drag & Drop Table view cell has weired buggy animation while dragging cell (Using long press gesture)

I'm following this to perform drag and drop table view cell but I don't know why I have buggy weird animation while dragging cell to other position in the table. I don't know what actually causes this type of issue, any help or suggestion would be appreciated. You can check the code and result below:
Code:
var longGesture: UILongPressGestureRecognizer!
var scrollRate: CGFloat = 0
var dragInitialIndexPath: IndexPath?
var dragCellSnapshot: UIView?
var scrollDisplayLink: CADisplayLink?
self.longGesture = UILongPressGestureRecognizer(target: self, action: #selector(onLongPressGesture(sender:)))
self.longGesture.minimumPressDuration = 0.3
self.tblEditProject.addGestureRecognizer(self.longGesture)
//MARK: tableCell reorder / long press
#objc func onLongPressGesture(sender: UILongPressGestureRecognizer) {
self.longGesture = sender
let state = sender.state
let locationInView = self.longGesture.location(in: self.tblEditProject)
let indexPath = self.tblEditProject.indexPathForRow(at: locationInView)
switch state {
case .began:
if indexPath != nil {
guard let currentIndexPath = indexPath else { return }
dragInitialIndexPath = currentIndexPath
self.scrollDisplayLink = CADisplayLink(target: self, selector: #selector(scrollTableWithCell))
self.scrollDisplayLink?.add(to: .main, forMode: .default)
guard let cell = self.tblEditProject.cellForRow(at: currentIndexPath) else { return }
dragCellSnapshot = self.snapshotOfCell(inputView: cell)
var center = cell.center
dragCellSnapshot?.center = center
dragCellSnapshot?.alpha = 0.0
self.tblEditProject.addSubview(dragCellSnapshot!)
UIView.animate(withDuration: 0.25, animations: { () -> Void in
center.y = locationInView.y
self.dragCellSnapshot?.center = center
self.dragCellSnapshot?.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
self.dragCellSnapshot?.alpha = 0.98
cell.alpha = 0.0
}, completion: { _ in
cell.isHidden = true
})
}
case .changed:
if indexPath != nil {
self.calculateScroll(gestureRecognizer: self.longGesture)
var center = dragCellSnapshot?.center
center?.y = locationInView.y
dragCellSnapshot?.center = center!
if indexPath != nil && indexPath != dragInitialIndexPath {
// update your data model
let dataToMove = self.arrEditProject[0].section[dragInitialIndexPath!.row]
self.arrEditProject[0].section.remove(at: dragInitialIndexPath!.row)
self.arrEditProject[0].section.insert(dataToMove, at: indexPath!.row)
self.tblEditProject.moveRow(at: dragInitialIndexPath!, to: indexPath!)
dragInitialIndexPath = indexPath
}
}
case .ended:
guard let persistedIndexPath = dragInitialIndexPath else { return }
guard let cell = self.tblEditProject.cellForRow(at: persistedIndexPath) else { return }
cell.isHidden = false
cell.alpha = 0.0
UIView.animate(withDuration: 0.25, animations: { () -> Void in
self.dragCellSnapshot?.center = cell.center
self.dragCellSnapshot?.transform = CGAffineTransform.identity
self.dragCellSnapshot?.alpha = 0.0
cell.alpha = 1.0
}, completion: { _ in
self.dragInitialIndexPath = nil
self.dragCellSnapshot?.removeFromSuperview()
self.dragCellSnapshot = nil
self.isUpdateContent = true
self.tblEditProject.reloadData()
/// For scrolling while dragging
self.scrollDisplayLink?.invalidate()
self.scrollDisplayLink = nil
self.scrollRate = 0
})
default:
guard let persistedIndexPath = dragInitialIndexPath else { return }
guard let cell = self.tblEditProject.cellForRow(at: persistedIndexPath) else { return }
cell.isHidden = false
cell.alpha = 0.0
UIView.animate(withDuration: 0.25) {
self.dragCellSnapshot?.center = cell.center
self.dragCellSnapshot?.transform = CGAffineTransform.identity
self.dragCellSnapshot?.alpha = 0.0
cell.alpha = 1.0
} completion: { _ in
self.dragInitialIndexPath = nil
self.dragCellSnapshot?.removeFromSuperview()
self.dragCellSnapshot = nil
}
}
}
func snapshotOfCell(inputView: UIView) -> UIView {
UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0.0)
inputView.layer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
let cellSnapshot = UIImageView(image: image)
cellSnapshot.layer.masksToBounds = false
cellSnapshot.layer.cornerRadius = 0.0
cellSnapshot.layer.shadowOffset = CGSize(width: -5.0, height: 0.0)
cellSnapshot.layer.shadowRadius = 5.0
cellSnapshot.layer.shadowOpacity = 0.4
return cellSnapshot
}
func calculateScroll(gestureRecognizer: UIGestureRecognizer) {
print("Call scroll table with cell")
let location = gestureRecognizer.location(in: self.tblEditProject)
var rect: CGRect = self.tblEditProject.bounds
/// adjust rect for content inset as we will use it below for calculating scroll zones
rect.size.height -= self.tblEditProject.contentInset.top
/// tell us if we should scroll and which direction
let scrollZoneHeight = rect.size.height / 6
let bottomScrollBeginning = self.tblEditProject.contentOffset.y + self.tblEditProject.contentInset.top + rect.size.height - scrollZoneHeight
let topScrollBeginning = self.tblEditProject.contentOffset.y + self.tblEditProject.contentInset.top + scrollZoneHeight
/// we're in the bottom zone
if (location.y >= bottomScrollBeginning)
{
self.scrollRate = (location.y - bottomScrollBeginning) / scrollZoneHeight
}
/// we're in the top zone
else if (location.y <= topScrollBeginning)
{
self.scrollRate = (location.y - topScrollBeginning) / scrollZoneHeight
}
else
{
self.scrollRate = 0
}
}
#objc func scrollTableWithCell() {
print("Call scroll table with cell")
let gestureLong = self.longGesture
let location = gestureLong?.location(in: self.tblEditProject)
let currentOffset = self.tblEditProject.contentOffset
var newOffset = CGPoint(x: currentOffset.x, y: currentOffset.y + self.scrollRate * 10)
if (newOffset.y < -self.tblEditProject.contentInset.top) {
newOffset.y = -self.tblEditProject.contentInset.top
} else if (self.tblEditProject.contentSize.height + self.tblEditProject.contentInset.bottom < self.tblEditProject.frame.size.height) {
newOffset = currentOffset
} else if (newOffset.y > (self.tblEditProject.contentSize.height + self.tblEditProject.contentInset.bottom) - self.tblEditProject.frame.size.height) {
newOffset.y = (self.tblEditProject.contentSize.height + self.tblEditProject.contentInset.bottom) - self.tblEditProject.frame.size.height;
}
self.tblEditProject.setContentOffset(newOffset, animated: false)
if let lction = location {
if (lction.y >= 0 && lction.y <= self.tblEditProject.contentSize.height + 50) {
var center = dragCellSnapshot?.center
center?.y = lction.y
dragCellSnapshot?.center = center ?? CGPoint.zero
var indexPath = self.tblEditProject.indexPathForRow(at: lction)
/// Check if the pointer is bigger than the table height to set indexPath as the last cell
if (self.tblEditProject.contentSize.height < lction.y) {
indexPath = IndexPath(row: (self.tblEditProject.numberOfRows(inSection: 0)) - 1, section: 0)
}
if let pathIndex = indexPath {
if !pathIndex.isEmpty && pathIndex != dragInitialIndexPath {
// update your data model
let dataToMove = self.arrEditProject[0].section[dragInitialIndexPath!.row]
self.arrEditProject[0].section.remove(at: dragInitialIndexPath!.row)
self.arrEditProject[0].section.insert(dataToMove, at: pathIndex.row)
self.tblEditProject.moveRow(at: dragInitialIndexPath!, to: pathIndex)
dragInitialIndexPath = pathIndex
}
}
}
}
}
Result:
Apple's already performed Drag&Drop mechanism for UITableView and UICollectionView (Apple Documentation, How to use it). You don't need to develop it from scratch.

Removing a UILongPressGesture default motions

I have a setting that allows the user to turn on and off the UILongPressGesture on a UITableView cell. I have a simple bool that I am checking if I should add or remove the gesture.
// Gesture Recognizer
let longPress: UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPressDetected(_:)))
if(options?.alphaOrder == false){
self.tableView.addGestureRecognizer(longPress)
}
else{
self.tableView.removeGestureRecognizer(longPress)
}
Long press method
func longPressDetected(_ sender: Any){
let longPress:UILongPressGestureRecognizer = sender as! UILongPressGestureRecognizer
let state:UIGestureRecognizerState = longPress.state
let location:CGPoint = longPress.location(in: self.tableView) as CGPoint
let indexPath = self.tableView.indexPathForRow(at: location)
var snapshot:UIView!
var sourceIndexPath:NSIndexPath?
if (holderView) != nil{
snapshot = holderView
}
if (beginningIndexPath) != nil{
sourceIndexPath = beginningIndexPath
}
switch(state){
case UIGestureRecognizerState.began:
if let test = indexPath{
sourceIndexPath = indexPath! as NSIndexPath
beginningIndexPath = sourceIndexPath
let cell:UITableViewCell = self.tableView.cellForRow(at: test)!
snapshot = self.customSnapShotFrom(view: cell)
holderView = snapshot
var center:CGPoint = cell.center
snapshot.center = center
snapshot.alpha = 0.0
self.tableView.addSubview(snapshot)
UIView.animate(withDuration: 0.25, animations:{
center.y = location.y
snapshot.center = center
snapshot.transform = CGAffineTransform(scaleX: 1.05, y: 1.05)
snapshot.alpha = 0.98
cell.alpha = 0.0
},completion:{ _ in
cell.isHidden = true})
}
break
case UIGestureRecognizerState.changed:
// print("changed")
var center:CGPoint = snapshot.center
center.y = location.y
snapshot.center = center
if let test = indexPath {
let bool = indexPath!.elementsEqual(beginningIndexPath as IndexPath)
if !bool {
self.updatePriorities(draggedOverIndexPath: test as NSIndexPath)
}
}
default:
// print("finished")
let cell:UITableViewCell = self.tableView.cellForRow(at: sourceIndexPath as! IndexPath)!
cell.isHidden = false
cell.alpha = 0.0
UIView.animate(withDuration: 0.25, animations: {
snapshot.center = cell.center;
snapshot.transform = .identity
snapshot.alpha = 0.0;
cell.alpha = 1.0;
}, completion: { _ in
sourceIndexPath = nil
snapshot.removeFromSuperview()
snapshot = nil
})
}
}
func customSnapShotFrom(view:UIView) -> UIView {
let snapshot:UIView = view.snapshotView(afterScreenUpdates: true)!
snapshot.layer.masksToBounds = false;
snapshot.layer.cornerRadius = 0.0;
snapshot.layer.shadowOffset = CGSize(width: 2.0, height: 2.0);
snapshot.layer.shadowRadius = 4.0;
snapshot.layer.shadowOpacity = 1.0;
return snapshot;
}
func updatePriorities(draggedOverIndexPath:NSIndexPath) {
let firstItem: Person = fetchedResultsController.object(at: beginningIndexPath as IndexPath)
let secondItem: Person = fetchedResultsController.object(at: draggedOverIndexPath as IndexPath)
firstItem.priority = Int32(draggedOverIndexPath.row)
secondItem.priority = Int32(beginningIndexPath.row)
beginningIndexPath = draggedOverIndexPath
coreDataStack.saveContext()
}
This works,but I noticed that even when the gesture is removed, I'm still able to long press on the table cell and move it. It doesn't rearrange the table cell, but I would like to stop this from happening.
Here's some semi-psuedo code that shows what I would recommend. This is better, because because every time the viewWillAppear the GestureRecognizer is updated.
class CustomViewController: UIViewController {
var longPress: UILongPressGestureRecognizer
required init() {
super.init(nibName: nil, bundle: nil)
longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressDetected(_:)))
self.tableView.addGestureRecognizer(longPress)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
longPress.isEnabled = (options?.alphaOrder == false)
}
func longPressDetected(_ sender: Any) {
...existing method...
}
}

Drag and Drop cells with UILongPressGestureRecognizer in UITableView

I am working on an app with a tableView in a ViewController. In this tableView I have sections and rows and I want my user to be able to long press, drag and drop cells in between sections with UILongPressGestureRecognizer.
With the following code my gesture recognizer works but at the moment that I try to drag the cell and drop it anywhere in the tableView, my app crashes. The crashes occur in two different lines. When the cell is long pressed and drag inside a section it crashes on this line: tableView.moveRowAtIndexPath(Path.initialIndexPath!, toIndexPath: indexPath!)
if I try to drag out of a section it crashes on this line: swap(&Categories.categories[indexPath!.row], &Categories.categories[Path.initialIndexPath!.row])
(the arrays with the data for each section and rows are in a separate class, named Categories. The array with sections is called "sections", and the one with rows is named "categories.")
I would appreciate any help with finding out why it fails and how can I fix it.
func setupLongPress() {
let longpress = UILongPressGestureRecognizer(target: self, action: "longPressGestureRecognized:")
tableView.addGestureRecognizer(longpress)
}
func longPressGestureRecognized(gestureRecognizer: UIGestureRecognizer) {
let longPress = gestureRecognizer as! UILongPressGestureRecognizer
let state = longPress.state
let locationInView = longPress.locationInView(tableView)
let indexPath = tableView.indexPathForRowAtPoint(locationInView)
struct My {
static var cellSnapshot : UIView? = nil
}
struct Path {
static var initialIndexPath : NSIndexPath? = nil
}
switch state {
case UIGestureRecognizerState.Began:
if indexPath != nil {
Path.initialIndexPath = indexPath
let cell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!
My.cellSnapshot = snapshopOfCell(cell)
var center = cell.center
My.cellSnapshot!.center = center
My.cellSnapshot!.alpha = 0.0
tableView.addSubview(My.cellSnapshot!)
UIView.animateWithDuration(0.25, animations: { () -> Void in
center.y = locationInView.y
My.cellSnapshot!.center = center
My.cellSnapshot!.transform = CGAffineTransformMakeScale(1.05, 1.05)
My.cellSnapshot!.alpha = 0.98
cell.alpha = 0.0
}, completion: { (finished) -> Void in
if finished {
cell.hidden = true
}
})
}
case UIGestureRecognizerState.Changed:
var center = My.cellSnapshot!.center
center.y = locationInView.y
My.cellSnapshot!.center = center
if ((indexPath != nil) && (indexPath != Path.initialIndexPath)) {
swap(&Categories.categories[indexPath!.row], &Categories.categories[Path.initialIndexPath!.row])
tableView.moveRowAtIndexPath(Path.initialIndexPath!, toIndexPath: indexPath!)
Path.initialIndexPath = indexPath
}
default:
let cell = tableView.cellForRowAtIndexPath(Path.initialIndexPath!) as UITableViewCell!
cell.hidden = false
cell.alpha = 0.0
UIView.animateWithDuration(0.5, animations: { () -> Void in
My.cellSnapshot!.center = cell.center
My.cellSnapshot!.transform = CGAffineTransformIdentity
My.cellSnapshot!.alpha = 0.0
cell.alpha = 1.0
}, completion: { (finished) -> Void in
if finished {
Path.initialIndexPath = nil
My.cellSnapshot!.removeFromSuperview()
My.cellSnapshot = nil
}
})
}
}
func snapshopOfCell(inputView: UIView) -> UIView {
UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0.0)
inputView.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext() as UIImage
UIGraphicsEndImageContext()
let cellSnapshot : UIView = UIImageView(image: image)
cellSnapshot.layer.masksToBounds = false
cellSnapshot.layer.cornerRadius = 0.0
cellSnapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0)
cellSnapshot.layer.shadowRadius = 1.0
cellSnapshot.layer.shadowOpacity = 0.2
return cellSnapshot
}
Thank you!

(Swift) Deleting UITableViewCell by dragging it out of the UITableView?

I currently have a UITableView with items from an array in it. It's possible to move the position of the UITableViewCell with anUILongPressGestureRecognizer freely around the Y and X axis, however I want to be able to delete the dragged UITableViewCell if it's moved outside of the UITableView.
I'm mostly aware I'll be using a Switch CaseUIGestureRecognizer.Ended to perform this but I'm currently at a loss on how to deal with it.
Here's the code:
func longPressGestureRecognized(gestureRecognizer: UIGestureRecognizer) {
let longPress = gestureRecognizer as! UILongPressGestureRecognizer
let state = longPress.state
var locationInView = longPress.locationInView(tblTasks)
var indexPath = tblTasks.indexPathForRowAtPoint(locationInView)
struct My {
static var cellSnapshot: UIView? = nil
}
struct Path {
static var initialIndexPath : NSIndexPath? = nil
}
switch state {
case UIGestureRecognizerState.Began:
if indexPath != nil {
Path.initialIndexPath = indexPath
let cell = tblTasks.cellForRowAtIndexPath(indexPath!) as UITableViewCell!
My.cellSnapshot = snapshotOfCell(cell)
var center = cell.center
My.cellSnapshot!.center = center
My.cellSnapshot!.alpha = 0.0
tblTasks.addSubview(My.cellSnapshot!)
UIView.animateWithDuration(0.25, animations: { () -> Void in
center.y = locationInView.y
My.cellSnapshot!.center = center
My.cellSnapshot!.transform = CGAffineTransformMakeScale(1.05, 1.05)
My.cellSnapshot!.alpha = 0.98
cell.alpha = 0.0
}, completion: { (finished) -> Void in
if finished {
cell.hidden = true
}
}) // End of animation sequence
} // End of IF statement
case UIGestureRecognizerState.Changed:
var center = My.cellSnapshot!.center
center.x = locationInView.x
center.y = locationInView.y
My.cellSnapshot!.center = center
if (indexPath != nil) && (indexPath != Path.initialIndexPath) {
swap(&taskMgr.tasks[indexPath!.row], &taskMgr.tasks[Path.initialIndexPath!.row])
tblTasks.moveRowAtIndexPath(Path.initialIndexPath!, toIndexPath: indexPath!)
Path.initialIndexPath = indexPath
}
default:
let cell = tblTasks.cellForRowAtIndexPath(Path.initialIndexPath!) as UITableViewCell!
cell.hidden = false
cell.alpha = 0.0
UIView.animateWithDuration(0.25, animations: { () -> Void in
My.cellSnapshot!.center = cell.center
My.cellSnapshot!.transform = CGAffineTransformIdentity
My.cellSnapshot!.alpha = 0.0
cell.alpha = 1.0
}, completion: { (finished) -> Void in
if finished {
Path.initialIndexPath = nil
My.cellSnapshot!.removeFromSuperview()
My.cellSnapshot = nil
}
})
} // End of switch
} // End of longPressGestureRecognized func
Any ideas?
You're on the right track but you need to embed your table view controller in the container of another view controller, and then put the gesture recognizer code in the container view controller.
This will help a lot: http://www.freshconsulting.com/create-drag-and-drop-uitableview-swift/
It's not 100% right but pretty close and I was able to use it to get exactly this going.

Resources