UICollectionViewController reordering does not work when embedded in a container view

Scooter's answer is right on! Here is the Swift 3 syntax version:

import UIKit

class ViewController: UIViewController
{
    // MARK: - IBOutlets
    @IBOutlet weak var uiCollectionView: UICollectionView!

    // MARK: - Lifecycle
    override func viewDidLoad()
    {
        super.viewDidLoad()

        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.handleLongGesture))
        self.uiCollectionView.addGestureRecognizer(longPressGesture)
    }


    // MARK: - Gesture recogniser
    @objc func handleLongGesture(gesture: UILongPressGestureRecognizer)
    {
        switch(gesture.state)
        {

        case .began:
            guard let selectedIndexPath = self.uiCollectionView.indexPathForItem(at: gesture.location(in: self.uiCollectionView)) else
            {
                break
            }

            self.uiCollectionView.beginInteractiveMovementForItem(at: selectedIndexPath)

        case .changed:
            self.uiCollectionView.updateInteractiveMovementTargetPosition(gesture.location(in: gesture.view!))

        case .ended:
            self.uiCollectionView.endInteractiveMovement()

        default:
            self.uiCollectionView.cancelInteractiveMovement()
        }
    }
}


// MARK: - UICollectionViewDataSource
extension ViewController: UICollectionViewDataSource
{
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
    {
        // TODO: Link to your data model
        return 20
    }


    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
    {
        // TODO: Link to your data model
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath)
        return cell
    }


    func collectionView(_ collectionView: UICollectionView,
                        moveItemAt sourceIndexPath: IndexPath,
                        to destinationIndexPath: IndexPath)
    {
        // TODO: Update your data model to reflect the change
    }
}


// MARK: - UICollectionViewDelegate
extension ViewController: UICollectionViewDelegate
{
    // TODO: Add any UICollectionViewDelegate here if needed.
}

Note that this code does not account for the touch location offset - so your cell will 'jump' to be centred under your finger as you start dragging. If you want to prevent that, then you would need to define in your UIViewController a CGPoint property (named initialGestureLocationInCell in the code below). And then substitute in the initial example with this:

[...]
        case .began:
        guard let selectedIndexPath = self.uiCollectionView.indexPathForItem(at: gesture.location(in: self.uiCollectionView)) else
        {
            break
        }

        let selectedCell = self.uiCollectionView.cellForItem(at: selectedIndexPath)!
        let gestureLocationInCell_RelativeToOrigin = gesture.location(in: selectedCell)
        let gestureLocationInCell_RelativeToCentre = CGPoint(x: gestureLocationInCell_RelativeToOrigin.x - selectedCell.frame.size.width/2,
                                                             y: gestureLocationInCell_RelativeToOrigin.y - selectedCell.frame.size.height/2)

        self.initialGestureLocationInCell = gestureLocationInCell_RelativeToCentre
        self.uiCollectionView.beginInteractiveMovementForItem(at: selectedIndexPath)

    case .changed:
        let gestureLocationInCollectionView = gesture.location(in: gesture.view!)
        let targetPosition = CGPoint(x: gestureLocationInCollectionView.x - self.initialGestureLocationInCell.x,
                                    y: gestureLocationInCollectionView.y - self.initialGestureLocationInCell.y)

        self.uiCollectionView.updateInteractiveMovementTargetPosition(targetPosition)
[...]

The issue here is that you put the UICollectionView inside a UIContainerView that is residing inside a UIViewController. This requires just a few more steps for the UICollectionView to work as expected.

Add the following to ViewDidLoad in your CollectionViewController:

    self.collectionView!.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: "handleLongGesture:"))

Then add the following function to your CollectionViewController:

    func handleLongGesture(gesture: UILongPressGestureRecognizer)
    {

    switch(gesture.state)
    {

    case UIGestureRecognizerState.Began:
        guard let selectedIndexPath = self.collectionView!.indexPathForItemAtPoint(gesture.locationInView(self.collectionView)) else
        {
            break
        }
        collectionView!.beginInteractiveMovementForItemAtIndexPath(selectedIndexPath)
    case UIGestureRecognizerState.Changed:
        collectionView!.updateInteractiveMovementTargetPosition(gesture.locationInView(gesture.view!))
    case UIGestureRecognizerState.Ended:
        collectionView!.endInteractiveMovement()
    default:
        collectionView!.cancelInteractiveMovement()
    }
}

Finally just make sure to include the following to ensure you handle the dataSource correctly:

    override func collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath,toIndexPath destinationIndexPath: NSIndexPath) {
    // Swap the values of the source and destination
}

Check out this link for more on this.

Hope this helped you out.