UICollectionView indexPathForItemAtPoint returns the same item despite scrolling

What is the correct syntax for using UICollectionView indexPathForItemAtPoint?

I use the following code to try to identify a cell that is in the center of a UICollectionView when I view it.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { //locate the scrollview which is in the centre CGPoint centerPoint = CGPointMake(self.collectionView.frame.size.width / 2, self.collectionView.frame.size.height /2); NSIndexPath *indexPathOfCentralCell = [self.collectionView indexPathForItemAtPoint:centerPoint]; } 

However, this always returns me the same indexPath, no matter what I scroll through.

What am I doing wrong?

+7
ios objective-c uicollectionview
source share
4 answers

You are viewing a static point in a static cell field. Yes, you always get the same cell.

To handle scrolling, you need to add the scrollview position to your check. Something like that:

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView { //locate the scrollview which is in the centre CGPoint centerPoint = CGPointMake(self.collectionView.frame.size.width / 2 + scrollView.contentOffset.x, self.collectionView.frame.size.height /2 + scrollView.contentOffset.y); NSIndexPath *indexPathOfCentralCell = [self.collectionView indexPathForItemAtPoint:centerPoint]; } 
+32
source share

An example of where you want to do this is when you want to capture a gesture in a UICollectionView, and then do something with a specific element in a UICollectionView that falls under the swipe gesture layout. The code below as a method in your UICollectionViewController will return the correct cell and allow for scrolling in the collection view.

 - (UICollectionViewCell *) cellForGesture:(id)sender { UISwipeGestureRecognizer * gesture = sender; CGPoint point = [gesture locationInView:self.view]; NSLog(@"Swipe location: %f, %f", point.x, point.y, nil); CGPoint pointInCollection = CGPointMake(point.x + self.collectionView.contentOffset.x, point.y + self.collectionView.contentOffset.y); NSIndexPath * indexPath = [self.collectionView indexPathForItemAtPoint:pointInCollection]; UICollectionViewCell * cell = [self.collectionView cellForItemAtIndexPath:indexPath]; return cell; } 

You can call the above method in this context (where revealSupplementalControls is a custom method in your UICollectionViewCell class):

 - (IBAction) swipeLeft:(id)sender { UICollectionViewCell * cell = [self cellForGesture:sender]; [cell revealSupplementalControls]; } 
+1
source share

Here's how to do it in Swift if you want to get a specific UICollectionViewCell with a UILongPressGesture

 @IBAction func cellAtLongPress(sender:UILongPressGestureRecognizer) { var location = sender.locationInView(self.view) // adjust the location to account for scrolling location.x += self.collectionView.contentOffset.x location.y += self.collectionView.contentOffset.y let indexPath = self.collectionView.indexPathForItemAtPoint(location) if (indexPath == nil) { print("not over cell") } else { // get the cell where the longPress occured let cell = self.collectionView.cellForItemAtIndexPath(indexPath!)! // you now have the the cell you pressed } } 
+1
source share

Duncan, this is what it works for me in Swift:

  let location = CGPointMake(self.clvGroups.frame.size.width / 2 + self.clvGroups.contentOffset.x, self.clvGroups.frame.size.height / 2 + self.clvGroups.contentOffset.y); if let ip = self.clvGroups.indexPathForItemAtPoint(location){ groupToUpdate.icon = self.dataSource![ip.row].icon } 

You must keep in mind the scrolling of the collection view.

0
source share

All Articles