Davemen
Davemen

Reputation: 156

Drag and Drop swap with Swift 2.0

I'm using a tableView and need to enable swapping items by dragging and dropping.

I'm mostly there but stuck on one problem. The item that is dragged to is not swapped with the item that is dragged from. Instead the new dragged item is added on top of the existing item and it simply shifts the existing item down one row below that.

 case UIGestureRecognizerState.Ended:
            var center = My.cellSnapshot!.center
            center.y = locationInView.y
            My.cellSnapshot!.center = center

            if ((indexPath != nil) && (indexPath != Path.initialIndexPath)) {
                //check to see if this is a valid place to swap
                var numberOfSlots:Int = 0 //the number of valid positions to swap
                numberOfSlots = thePlayers[Path.initialIndexPath!.row].SwapPosition.count
                for index in 1...numberOfSlots {
                    if thePlayers[Path.initialIndexPath!.row].SwapPosition[index - 1] == thePlayers[indexPath!.row].PlayerPosition {
                        //this is a valid swap
                        print("Swap it!")
                        OkToSwap = true
                        break
                    }
                    else {
                        print (thePlayers[Path.initialIndexPath!.row].SwapPosition[index - 1])
                    }
                }
            }
            if OkToSwap == true {  //if this is a valid slot for a swap, then swap it.
                    //  swap(&itemsArray[indexPath!.row], &itemsArray[Path.initialIndexPath!.row])
                    //***TODO: Add Webservice call to swap on the website***

                    //move the selectedRow to the original (dragged from) position
                    tableView.moveRowAtIndexPath(Path.initialIndexPath!, toIndexPath: indexPath!)
                    My.cellSnapshot?.alpha = 0.0
                    let cell = tableView.cellForRowAtIndexPath(Path.initialIndexPath!) as UITableViewCell!
                    cell.alpha = 1

            }
                    //put it back
                    let cell = tableView.cellForRowAtIndexPath(indexPath!) as UITableViewCell!
                    cell.hidden = false
                    cell.alpha = 0.0
                    UIView.animateWithDuration(0.25, animations: { () -> Void in
                        My.cellSnapshot!.center =  originalCenter
                        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
                            }
                    })

        default:
            let cell = tableView.cellForRowAtIndexPath(Path.initialIndexPath!) as UITableViewCell!
            cell.hidden = false
            cell.alpha = 0.0
            // Clean up.

            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
                    }
            })
        }
    }

any idea how to do a true swap of rows using Swift 2.0 - I've found a few sample code snippets but syntax changes have made them not work and I'm stuck.

Upvotes: 0

Views: 378

Answers (1)

Critter
Critter

Reputation: 462

I was able to get this bit working with Swift 2.0

    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 = 5.0
    cellSnapshot.layer.shadowOpacity = 0.4
    return cellSnapshot
}

// MARK: Gesture Methods
func longPressGestureRecognized(gestureRecognizer: UIGestureRecognizer) {
    let longPress = gestureRecognizer as! UILongPressGestureRecognizer

    let state = longPress.state

    var locationInView = longPress.locationInView(tableView)

    var 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
                    }
            })
        }
        break
    case UIGestureRecognizerState.Changed:
        var center = My.cellSnapshot!.center
        center.y = locationInView.y
        My.cellSnapshot!.center = center
        if ((indexPath != nil) && (indexPath != Path.initialIndexPath)) {
            //------=-=-=-=[    
            // This line errors when it is uncommented. When I comment it out, the error is gone,
            // and the cells /do/ reorder.. ¯\_(ツ)_/¯
            //swap(&itemsArray[indexPath!.row], &itemsArray[Path.initialIndexPath!.row])
            tableView.moveRowAtIndexPath(Path.initialIndexPath!, toIndexPath: indexPath!)
            Path.initialIndexPath = indexPath
        }
        break
    default:
        let cell = tableView.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
                }
        })
        break

    }//.switch


}// .longPressGestureRecognized

Upvotes: 1

Related Questions