CollectionView Cell gets shifted to right after ho

2019-07-05 23:53发布

I have a collectionView Cell that is of the same size of my CollectionView i.e. one Cell at a time is displayed on the screen and I want minimum separation of 10 between cells, the problem is when I scroll the cell the cells aren't properly fitting the whole screen, and the shifting of cell is increased after every scroll. (Check screenshots for better understanding)

This is 3rd cell

This is 6th cell

enter image description here

2条回答
做自己的国王
2楼-- · 2019-07-06 00:38

I assume you have set pagingEnabled for the collection view. It inherits this property from UIScrollView (because UICollectionView is a subclass of UIScrollView).

The problem is that the collection view uses its own width (320 points in your post) as the width of a page. Each of your cells is the same width as the collection view, but then you have a 10 point “gutter” between the cells. This means that the distance from the left edge of cell 0 to the left edge of cell 1 is 320 + 10 = 330 points. So when you scroll to show cell 1, the collection view stops scrolling at offset 320 (its own width), but cell 1 actually starts at offset 330.

The easiest fix is probably to turn off pagingEnabled and implement paging yourself by overriding scrollViewWillEndDragging(_:withVelocity:targetContentOffset:) in your collection view delegate, like this:

override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
    guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout else { return }

    let pageWidth = scrollView.bounds.size.width + flowLayout.minimumInteritemSpacing

    let currentPageNumber = round(scrollView.contentOffset.x / pageWidth)
    let maxPageNumber = CGFloat(collectionView?.numberOfItems(inSection: 0) ?? 0)

    // Don't turn more than one more page when decelerating, and don't go beyond the first or last page.
    var pageNumber = round(targetContentOffset.pointee.x / pageWidth)
    pageNumber = max(0, currentPageNumber - 1, pageNumber)
    pageNumber = min(maxPageNumber, currentPageNumber + 1, pageNumber)
    targetContentOffset.pointee.x = pageNumber * pageWidth
}

You'll also want to set the item size to match the device screen size, and set the deceleration rate to fast:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    guard let flowLayout = collectionViewLayout as? UICollectionViewFlowLayout, let collectionView = collectionView else { return }
    flowLayout.itemSize = collectionView.bounds.size

    collectionView.decelerationRate = UIScrollViewDecelerationRateFast
}

Result:

demo

查看更多
等我变得足够好
3楼-- · 2019-07-06 00:49

The reason is that you have not taken the minimum separation of 10 while setting width of the cell(320). Hence this 10 is getting accumulated each time to scroll.

So you have to subtract 10 out of 320 while setting the width, so the width should be 310 IMO.

查看更多
登录 后发表回答