UICollectionView Horizontal Paging not centered

前端 未结 11 1694
感动是毒
感动是毒 2020-12-02 09:32

I have a horizontal scrolling collectionView with each cell the size of the view. When I page through the collectionView it doesn\'t page by cell. The cells aren\'t in the c

11条回答
  •  不知归路
    2020-12-02 09:46

    Being able to have cells that are smaller the collectionView frame with space between the cells allows for hinting to the user that there other cells either side to scroll to which is a big win for UX. But for the centering of the pages doesn't work as expected with each cell progressively becoming more offset as the user scrolls. I've found the following to work well. The centering/snapping animation on each cell is almost invisible to user since it is only tweaking where the collectionView scrolling would end naturally rather than jerking the collectionView to quickly scroll to another indexPath. It's still important to to have the sectionInset property set large enough to allow cell not to stick to the containing frame edges. Also since there are spaces between the cells the target could land on an indexPath of nil which would cause the collectionView to scroll back to the start. I've fixed this offsetting a little and then trying again but different approaches could be taken here.

    - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
                     withVelocity:(CGPoint)velocity
              targetContentOffset:(inout CGPoint *)targetContentOffset
    {
        //Ensure the scrollview is the collectionview we care about
        if (scrollView == self.collectionView) {
    
            // Find cell closest to the frame centre with reference from the targetContentOffset.
            CGPoint frameCentre = self.collectionView.center;
            CGPoint targetOffsetToCentre = CGPointMake((* targetContentOffset).x + frameCentre.x, (* targetContentOffset).y + frameCentre.y);
    
            NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:targetOffsetToCentre];
    
                //Check for "edgecase" that the target will land between cells and then find a close neighbour to prevent scrolling to index {0,0}.
            while (!indexPath) {
                targetOffsetToCentre.x += ((UICollectionViewFlowLayout *)self.collectionView.collectionViewLayout).minimumInteritemSpacing;
                indexPath = [self.collectionView indexPathForItemAtPoint:targetOffsetToCentre];
            }
    
            // Find the centre of the target cell
            CGPoint centreCellPoint = [self.collectionView layoutAttributesForItemAtIndexPath:indexPath].center;
    
            // Calculate the desired scrollview offset with reference to desired target cell centre.
            CGPoint desiredOffset = CGPointMake(centreCellPoint.x - frameCentre.x, centreCellPoint.y - frameCentre.y);
            *targetContentOffset = desiredOffset;
        }
    }
    

提交回复
热议问题