0

I'm using a collection view and I'm trying to set up peek & pop to work with it. I've overridden:

func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController?

I'm trying to retrieve the index path for the item I'm clicking on by using the location variable.

Location appears to be correct but for some reason collectionView.indexPathForItem(at: location) is returning the wrong index path.

I have an idea of how to solve this issue, but I'm not sure that it is possible in Swift. Here is my thought:

Use the function indexPathForVisibleItems to retrieve all IndexPaths available. Loop through these IndexPaths and use a function that would be called something like locationForItem(at: indexPath) if it existed. I could then find the correct IndexPath based on its location.

If this is not possible, I'd be wondering if anyone else has had the same problem, where it is returning the completely wrong index path? What I believe is happening is that the spot that I'm clicking might have multiple cells, and it is grabbing the top cell in the view hierarchy, and returning the indexPath for that top cell, which might be the only one in this Z-index.

Is it possible to retrieve all index paths at a location?

Code:

override func viewDidLoad()
    if traitCollection.forceTouchCapability == .available {
        registerForPreviewing(with: self, sourceView: collectionView)
    }

override func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
    guard let indexPath = collectionView.indexPathForItem(at: location)...
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Logan
  • 1,172
  • 9
  • 23
  • Please post the relevant code where you try to find `indexPathForItem(at: location)`, and how you register for previewing. What is likely happening is that the `location` you're passing is in reference to some other view's coordinate plane (probably the controller's main view), so you need to convert the point to the collection view's coordinates first. – Connor Neville Oct 06 '17 at 19:04
  • Regarding the latter part of your post, why would a touch contain more than 1 collection view cell? That shouldn't happen. – Connor Neville Oct 06 '17 at 19:05
  • 1
    Have you confirmed that this isn't simply a coordinate system issue? The `location` is in the coordinate system of `previewingContext.sourceView`. Is this your collection view? If not, you need to convert the point into your collection view's coordinate system using `collectionView.convert(location, from: previewingContext.sourceView)`. – Lily Ballard Oct 06 '17 at 19:08
  • Have you used view as the source view in `registerForPreviewingWithDelegate(self, sourceView: view)`? – Pranav Kasetti Oct 06 '17 at 19:09
  • Added in code in my question... – Logan Oct 06 '17 at 19:23
  • For test purposes, I ran a `collectionView.indexPathForItem()` on every single location possible on the entire screen, and not one produced the correct index path. when I do `collectionView.indexPathsForVisibleItems` I can see a list of completely different index paths than I retrieved here, and one of those is actually the correct one... – Logan Oct 06 '17 at 19:25
  • Make sure you're converting the point to the coordinate system of the collectionView.contentView. – GetSwifty Oct 06 '17 at 22:02
  • try to do that let convertedLocation = tableView.convert(location, from: self.view) – Yılmaz edis Feb 16 '23 at 14:16

0 Answers0