1

I have a collectionview controller with custom 2-columns layout:

class CVLayout: UICollectionViewFlowLayout {

override init() {
    super.init()
    setupLayout()
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    setupLayout()
}

override var itemSize: CGSize {
    set {

    }
    get {
        let numberOfColumns: CGFloat = 2

        let itemWidth = (self.collectionView!.frame.width - (numberOfColumns - 1)) / numberOfColumns
        return CGSize(width: itemWidth, height: itemWidth)
    }
}

func setupLayout() {
    minimumInteritemSpacing = 1
    minimumLineSpacing = 1
    scrollDirection = .horizontal
}

}

In my controller I set

class ViewController: UICollectionViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    collectionView?.isScrollEnabled = true
    collectionView?.isPagingEnabled = true
}

I have 7 items, 6 items are displayed on the screen and I expect to see one item on the next page, but instead I see 4 (3 from the previous page) I tried to play with number of sections and items in section, but it doesn't help. What I've found from other topics is that default paging should be by screen, not by cell (in my case a column). What am I doing wrong?

Elena Rubilova
  • 367
  • 4
  • 16

2 Answers2

1

If I understand your question, I do not think you are doing anything wrong per se. The content size of the collection view is determined (in part) by the item size. Right now that is approximately the width of 3 items (or a page and a half of content). I think you need to override the collection view's content size property to reflect full pages of content (in width) to achieve the desired effect.

override var collectionViewContentSize: CGSize {

    if  let collectionView = collectionView {
        let numberOfItems = collectionView.numberOfItems(inSection: 0)
        let pages = numberOfItems/2
        let size =  CGSize(width: collectionView.frame.width * CGFloat(pages), height: collectionView.frame.height)
        return size
    }

    return CGSize(width: 0, height: 0)
}

Please see this answer How to expand UICollectionView contentSize when paging enable?. It is a bit old but I think it is trying to solve the same issue.

Community
  • 1
  • 1
Dennis W.
  • 646
  • 6
  • 7
  • That's what I was looking for! I changed your code a bit (calculation of number of pages). And I also had to subtract nav bar's height because otherwise my collection view was jumping up on scroll. Thanks! – Elena Rubilova Feb 09 '17 at 04:20
0

First of all UICollectionViewFlowLayout doesn't support paging

There are two solution that i think

first

use UIScrollView add 7 items simply with paging option

second

use UICollectionView modifying your UICollectionViewFlowLayout

subclass UICollectionViewFlowLayout to support paging

ex)

In Swift3

class CustomCollectionViewFlowLayout: UICollectionViewFlowLayout {
    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        var offsetAdjustment = CGFloat.greatestFiniteMagnitude
        let horizontalOffset = proposedContentOffset.x
        let targetRect = CGRect(x: proposedContentOffset.x, y: 0, width: self.collectionView!.bounds.size.width, height: self.collectionView!.bounds.size.height)
        for layoutAttributes in super.layoutAttributesForElements(in: targetRect)! {
            let itemOffset = layoutAttributes.frame.origin.x
            if abs(itemOffset - horizontalOffset) < abs(offsetAdjustment){
                offsetAdjustment = itemOffset - horizontalOffset
            }
        }
        return CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
    }
}

you can find more information searching UICollectionViewFlowLayout with Paging

Cruz
  • 2,602
  • 19
  • 29