CollectionView Drag and Drop when embedded in PageViewController

197 views Asked by At

When using drag and drop with a UICollectionView embedded in a UIPageViewController, the delegate immediately triggers didExit when paging.

  1. Begin Drag and Drop gesture
  2. Page to new view
  3. CollectionDropDelegate immediately fires:
  • newCV.didEnter
  • oldCV.didExit
  • newCV.didExit

newCV.didUpdate is never called. If we let go of the drop at this point it cancels. My PageViewController is not fullscreen, so if I move the drag outside and back in I can still perform the drop after paging, but it's a bad user experience.

Notes:

  • Not using UICollectionViewController
  • CollectionView gets added to the UIViewController hierarchy in viewDidLoad

Any ideas?

1

There are 1 answers

0
hidden-username On

I was able to resolve this by toggling collectionView.isUserInteractionEnabled. Figuring out where in the lifecycle to do this was a bit challenging, and ultimately I ended up using the UIPageViewControllerDelegate didFinishAnimating...

So in my ContentViewController.viewDidLoad, I set collectionView.isUserInteractionEnabled = false and then in the delegate, I need to conditionally enable/disable the collection views.

func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { 
    if completed {
        guard let showing = pageViewController.viewControllers?.first as? DayViewController else {
            assertionFailure()
            return
        }
        
        // Disable All
        previousViewControllers.forEach {
            if let dayVC = $0 as? DayViewController {
                dayVC.collectionView?.isUserInteractionEnabled = false
            }
        }
        // Enable Showing
        showing.collectionView?.isUserInteractionEnabled = true
    } else {
        
        guard let showing = previousViewControllers.first as? DayViewController else {
            assertionFailure()
            return
        }
        
        // Disable All
        viewControllers?.forEach {
            if let dayVC = $0 as? DayViewController {
                dayVC.collectionView?.isUserInteractionEnabled = false
            }
        }
        // Enable Showing
        showing.collectionView?.isUserInteractionEnabled = true
    }
}