UICollectionView indexPathForItemAtPoint returning same item despite scrolling

不想你离开。 提交于 2019-12-21 09:26:19

问题


What is the correct syntax for using UICollectionView's indexPathForItemAtPoint?

I'm using the following code to try to identify the cell that is at the centre of the UICollectionView as I scroll through 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 gives me the same indexPath back, no matter how I scroll.

What am I doing wrong?


回答1:


You are looking up a static point in a static field of cells. Yes you will always get the same cell.

In order to deal with scrolling you need to add the scrollview's position into your check. Something like this:

- (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];
}



回答2:


An example of where you'd want to do this is when you want to capture a gesture on the UICollectionView, and then do something with the specific item in the UICollectionView that falls under the location of the swipe gesture. The code below as a method in your UICollectionViewController will return the correct cell, and accounts for scrolling within 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 might call the above method in a context like this (where revealSupplementalControls is a custom method on your UICollectionViewCell class):

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



回答3:


Here is how to do it in Swift if you want to retrieve 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
    }
}



回答4:


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 have to keep in mind the scrolling view of collection view.



来源:https://stackoverflow.com/questions/21312184/uicollectionview-indexpathforitematpoint-returning-same-item-despite-scrolling

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!