klcjr89
klcjr89

Reputation: 5902

UICollectionView find center cell when content inset is used

I'm trying to figure out how to find the center most cell of my UICollectionView, which is set to only scroll horizontally.

I tried this SO: how to get indexPath for cell which is located in the center of UICollectionView but it isn't working out, I think because I'm using the contentInset property of my UICollectionView.

What I'm doing is setting the contentInset left and right of the flow layout to exactly 1/2 of self.view's bounds width minus 1/2 of itemSize width. I'm not sure how to calculate the center most cell due to this. I'd appreciate any help offered. Code:

CGPoint cellCenter = CGPointMake((self.collectionView.center.x + 
self.collectionView.contentOffset.x) - 
(self.sampleFlowLayout.sectionInset.left + 
self.sampleFlowLayout.sectionInset.right), self.collectionView.center.y);

NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:cellCenter];

if (indexPath)
{
    NSInteger tag = [self.collectionView cellForItemAtIndexPath:indexPath].tag;

    if (tag != self.currentSample)
    {
        self.currentSample = tag;

        self.imageView.image = [self sampleImageWithOption:self.currentSample];
    }
}

- (void)viewDidLoad
{
    self.sampleFlowLayout = [[UICollectionViewFlowLayout alloc]init];

    CGSize itemSize = CGSizeMake(63, 63);   

    self.sampleFlowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;

    self.sampleFlowLayout.sectionInset = UIEdgeInsetsMake(0, (self.view.bounds.size.width / 2) - (itemSize.width / 2), 0, (self.view.bounds.size.width / 2) - (itemSize.width / 2));
}

Upvotes: 0

Views: 1075

Answers (1)

klcjr89
klcjr89

Reputation: 5902

I figured this out myself using help from this answer: https://stackoverflow.com/a/22696037/1533438

Final code:

- (void)snapCollectionView:(UICollectionView *)collectionView withProposedOffset:(CGPoint)proposedOffset
{
    CGRect cvBounds = collectionView.bounds;
    CGFloat halfWidth = cvBounds.size.width * 0.5;
    CGFloat proposedContentOffsetCenterX = proposedOffset.x + halfWidth;

    NSArray *attributesArray = [collectionView.collectionViewLayout layoutAttributesForElementsInRect:cvBounds];

    UICollectionViewLayoutAttributes *candidateAttributes;

    for (UICollectionViewLayoutAttributes *attributes in attributesArray)
    {
        if (attributes.representedElementCategory !=
            UICollectionElementCategoryCell)
        {
            continue;
        }

        if (!candidateAttributes)
        {
            candidateAttributes = attributes;
            continue;
        }

        if (fabsf(attributes.center.x - proposedContentOffsetCenterX) <
            fabsf(candidateAttributes.center.x - proposedContentOffsetCenterX))
        {
            candidateAttributes = attributes;
        }
    }

    CGPoint offset = CGPointMake(candidateAttributes.center.x - halfWidth, proposedOffset.y);
    [collectionView setContentOffset:offset animated:YES];

    CGPoint cellCenter = CGPointMake(offset.x + self.sampleCollectionView.bounds.size.width / 2.0, self.sampleCollectionView.bounds.size.height / 2.0);

    NSIndexPath *indexPath = [self.sampleCollectionView indexPathForItemAtPoint:cellCenter];

    if (indexPath)
    {
        NSInteger tag = [self.sampleCollectionView cellForItemAtIndexPath:indexPath].tag;

        if (tag != self.currentSample)
        {
            self.currentSample = tag;

            UIImage *image;

            if (self.currentSample == 0)
            {
                image = self.image;
            }
            else
            {
                image = [self sampleImageWithOption:self.currentSample];
            }

            dispatch_async(dispatch_get_main_queue(),
            ^{
                self.imageView.image = image;
            });
        }
    }
}

Upvotes: 0

Related Questions