title: Drag and reorder - UICollectionview with sections
body: <p>Is that possible to do drag and reorder from one section to another section from collectionview - iOS 9.</p>
  
  <p>Every time am dragging from 1st section to drop at 4th section am getting below crash,</p>
  
  <p>Assertion failure in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:</p>
  
  <pre><code>    func collectionView(collectionView: UICollectionView, moveItemAtIndexPath sourceIndexPath: NSIndexPath,toIndexPath destinationIndexPath: NSIndexPath)
  
          {
  
          let sequence = ArrayrelatedSequence[sourceIndexPath.section] as! SEQ_Sequence
  
          relIndexCards = sequence.rel_indexCard
  
          if relIndexCards.count &gt; 0 {
  
              ArrayIndexcard = []
  
              let arr1: NSMutableArray = []
  
              for item in relIndexCards {
  
                  arr1.addObject(item)
              }
  
              let descriptor: NSSortDescriptor = NSSortDescriptor(key: "keyP_IndexCard_ID", ascending: false)
              let arrNew:NSArray = arr1.sortedArrayUsingDescriptors([descriptor])
  
              let i = 0
              for item in arrNew
              {
                  ArrayIndexcard.insert(item as! NSManagedObject, atIndex: i)
                  i+1
              }
  
          }
  
          let temp = self.ArrayIndexcard.removeAtIndex(sourceIndexPath.item)
  
          self.ArrayIndexcard.insert(temp, atIndex: destinationIndexPath.item)
  
  
          if islongPressed_Indexcard == true
          {
              islongPressed_Indexcard = false
  
              let managedContext = appDelegate.managedObjectContext
  
              var i = 0
  
              for update in ArrayIndexcard
              {
  
                  i = i+1
  
                  update.setValue(i, forKey: "keyP_IndexCard_ID")
  
              }
  
              do {
                  try managedContext.save()
  
                  collectionview_in_outline.reloadData()
  
              } catch let nserror as NSError {
  
                  print("Unresolved error \(nserror), \(nserror.userInfo)")
                  abort()
              }
  
          }
      }
  </code></pre>
  
  <p>My flow layout code below,</p>
  
  <pre><code> class CustomFlowLayout: UICollectionViewFlowLayout {
  
  var longPress: UILongPressGestureRecognizer!
  var originalIndexPath: NSIndexPath?
  var draggingIndexPath: NSIndexPath?
  var draggingView: UIView?
  var dragOffset = CGPointZero
  
  override func prepareLayout() {
      super.prepareLayout()
  
      installGestureRecognizer()
  }
  
  func applyDraggingAttributes(attributes: UICollectionViewLayoutAttributes) {
      attributes.alpha = 0
  }
  
  override func layoutAttributesForElementsInRect(rect: CGRect) -&gt; [UICollectionViewLayoutAttributes]? {
      let attributes = super.layoutAttributesForElementsInRect(rect)
      attributes?.forEach { a in
          if a.indexPath == draggingIndexPath {
              if a.representedElementCategory == .Cell {
                  self.applyDraggingAttributes(a)
              }
          }
      }
      return attributes
  }
  
  override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -&gt; UICollectionViewLayoutAttributes? {
      let attributes = super.layoutAttributesForItemAtIndexPath(indexPath)
      if let attributes = attributes where indexPath == draggingIndexPath {
          if attributes.representedElementCategory == .Cell {
              applyDraggingAttributes(attributes)
          }
      }
      return attributes
  }
  
  func installGestureRecognizer() {
      if longPress == nil {
          longPress = UILongPressGestureRecognizer(target: self, action: #selector(CustomFlowLayout.handleLongPress(_:)))
          longPress.minimumPressDuration = 0.2
          collectionView?.addGestureRecognizer(longPress)
      }
  }
  
  func handleLongPress(longPress: UILongPressGestureRecognizer) {
  
  
      let location = longPress.locationInView(collectionView!)
      switch longPress.state {
      case .Began: startDragAtLocation(location)
      case .Changed: updateDragAtLocation(location)
      case .Ended: endDragAtLocation(location)
      default:
          break
      }
  }
  
  func startDragAtLocation(location: CGPoint) {
      guard let cv = collectionView else { return }
      guard let indexPath = cv.indexPathForItemAtPoint(location) else { return }
      guard cv.dataSource?.collectionView?(cv, canMoveItemAtIndexPath: indexPath) == true else { return }
      guard let cell = cv.cellForItemAtIndexPath(indexPath) else { return }
  
      originalIndexPath = indexPath
      draggingIndexPath = indexPath
      draggingView = cell.snapshotViewAfterScreenUpdates(true)
      draggingView!.frame = cell.frame
      cv.addSubview(draggingView!)
  
      dragOffset = CGPointMake(draggingView!.center.x - location.x, draggingView!.center.y - location.y)
  
      draggingView?.layer.shadowPath = UIBezierPath(rect: draggingView!.bounds).CGPath
      draggingView?.layer.shadowColor = UIColor.blackColor().CGColor
      draggingView?.layer.shadowOpacity = 0.8
      draggingView?.layer.shadowRadius = 10
  
      invalidateLayout()
  
      UIView.animateWithDuration(0.4, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: [], animations: {
          self.draggingView?.alpha = 0.95
          self.draggingView?.transform = CGAffineTransformMakeScale(1.2, 1.2)
          }, completion: nil)
  }
  
  func updateDragAtLocation(location: CGPoint) {
      guard let view = draggingView else { return }
      guard let cv = collectionView else { return }
  
      view.center = CGPointMake(location.x + dragOffset.x, location.y + dragOffset.y)
  
  
  
      if let newIndexPath = cv.indexPathForItemAtPoint(location) {   
               **cv.moveItemAtIndexPath(draggingIndexPath!, toIndexPath: newIndexPath)**
          draggingIndexPath = newIndexPath
  
      }
  }
  
  func endDragAtLocation(location: CGPoint) {
      guard let dragView = draggingView else { return }
      guard let indexPath = draggingIndexPath else { return }
      guard let cv = collectionView else { return }
      guard let datasource = cv.dataSource else { return }
  
      let targetCenter = datasource.collectionView(cv, cellForItemAtIndexPath: indexPath).center
  
      let shadowFade = CABasicAnimation(keyPath: "shadowOpacity")
      shadowFade.fromValue = 0.8
      shadowFade.toValue = 0
      shadowFade.duration = 0.4
      dragView.layer.addAnimation(shadowFade, forKey: "shadowFade")
  
      UIView.animateWithDuration(0.4, delay: 0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: [], animations: {
          dragView.center = targetCenter
          dragView.transform = CGAffineTransformIdentity
  
      }) { (completed) in
  
          if !indexPath.isEqual(self.originalIndexPath!) {
              datasource.collectionView?(cv, moveItemAtIndexPath: self.originalIndexPath!, toIndexPath: indexPath)
          }
  
          dragView.removeFromSuperview()
          self.draggingIndexPath = nil
          self.draggingView = nil
          self.invalidateLayout()
      }
  
      NSNotificationCenter.defaultCenter().postNotificationName("Needtorefresh", object: nil)
  
      collectionView?.reloadData()
  
  }
  </code></pre>
  
  <p>}</p>