Reordering is working in iOS9 when I add this to my UICollectionViewController
subclass
override func collectionView(collectionView: UICollectionView,
moveItemAtIndexPath sourceIndexPath: NSIndexPath,
toIndexPath destinationIndexPath: NSIndexPath)
It does not work when this UICollectionViewController
subclass is embedded in a container view.
I've made a demo of the problem here
Any ideas on why or how to fix it?
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)
[...]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With