UICollectionView Cell Scroll to centre

后端 未结 6 1229
无人共我
无人共我 2021-02-02 00:28

I am using UICollectionView in my UIViewController.

My collectionview properties are set as below.

\"enter

6条回答
  •  暖寄归人
    2021-02-02 01:24

    You can override targetContentOffsetForProposedContentOffset:withScrollingVelocity: method in your UICollectionViewLayout subclass and calculate your offset there like this:

    @property (nonatomic, assign) CGFloat previousOffset;
    @property (nonatomic, assign) NSInteger currentPage;
    
    ...
    
    - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
        NSInteger itemsCount = [self.collectionView.dataSource collectionView:self.collectionView numberOfItemsInSection:0];
    
        // Imitating paging behaviour
        // Check previous offset and scroll direction
        if ((self.previousOffset > self.collectionView.contentOffset.x) && (velocity.x < 0.0f)) {
            self.currentPage = MAX(self.currentPage - 1, 0);
        } else if ((self.previousOffset < self.collectionView.contentOffset.x) && (velocity.x > 0.0f)) {
            self.currentPage = MIN(self.currentPage + 1, itemsCount - 1);
        }
    
        // Update offset by using item size + spacing
        CGFloat updatedOffset = (self.itemSize.width + self.minimumInteritemSpacing) * self.currentPage;
        self.previousOffset = updatedOffset;
    
        return CGPointMake(updatedOffset, proposedContentOffset.y);
    }
    

    EDIT: thanks for pointing this out, forgot to say that you have to disable paging first:

    self.collectionView.pagingEnabled = NO;
    

    UPDATE: attaching Swift 4.2 version

    ...
    collectionView.isPagingEnabled = false
    ...
    
    class YourCollectionLayoutSubclass: UICollectionViewFlowLayout {
    
        private var previousOffset: CGFloat = 0
        private var currentPage: Int = 0
    
        override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
            guard let collectionView = collectionView else {
                return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
            }
    
            let itemsCount = collectionView.numberOfItems(inSection: 0)
    
            // Imitating paging behaviour
            // Check previous offset and scroll direction
            if previousOffset > collectionView.contentOffset.x && velocity.x < 0 {
                currentPage = max(currentPage - 1, 0)
            } else if previousOffset < collectionView.contentOffset.x && velocity.x > 0 {
                currentPage = min(currentPage + 1, itemsCount - 1)
            }
    
            // Update offset by using item size + spacing
            let updatedOffset = (itemSize.width + minimumInteritemSpacing) * CGFloat(currentPage)
            previousOffset = updatedOffset
    
            return CGPoint(x: updatedOffset, y: proposedContentOffset.y)
        }
    }
    

提交回复
热议问题