1
votes

Before I use customized UICollectionViewFlowLayout, the scroll function works Fine, but when I set my layout to UICollectionView, it can't scroll anymore, but all contents display well because my layout works.

I want to make PinterestLayout, so I created my layout displayed as the following photo. I am try to use this lay out into my Instagram-style app with UICollection header and cell

My Code for my layout is the following:


class MyLayout : UICollectionViewFlowLayout{

     fileprivate let numberOfColumns = 2
     weak var delegate : MyLayoutDelegate!
     fileprivate var cache = [UICollectionViewLayoutAttributes]()
     fileprivate var contentHeight : CGFloat = 0
     fileprivate var contentWidth : CGFloat{
         guard let collectionView = collectionView else {return 0.0}
         let insets = collectionView.contentInset
         return collectionView.bounds.width - (insets.left + insets.right)
     }
     override var collectionViewContentSize: CGSize{
         return CGSize(width: contentWidth, height: contentHeight)
     }

     override init() {
         super.init()
         self.minimumLineSpacing = 1
         self.minimumInteritemSpacing = 1
     }

     required init?(coder: NSCoder) {
         fatalError("init(coder:) has not been implemented")
     }

     override func prepare() {
         guard let collection = collectionView else {return}
         let columnWidth = contentWidth / CGFloat(numberOfColumns)
         let xOffset: [CGFloat] = [0,columnWidth]
         var yOffset = [CGFloat](repeating: 190, count: numberOfColumns)


         var columnToPlacePhoto = 0
         for item in 0 ..< collection.numberOfItems(inSection: 0){

             let indexPath = IndexPath(item: item, section: 0)
             let photoHeight : CGFloat = delegate.collectionView(collection, numberOfColumns: numberOfColumns, heightForPhotoAtIndexPath: indexPath)
             let frame = CGRect(x: xOffset[columnToPlacePhoto], y: yOffset[columnToPlacePhoto], width: columnWidth, height: photoHeight)
             let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
             attributes.frame = frame
             self.cache.append(attributes)

             yOffset[columnToPlacePhoto] = yOffset[columnToPlacePhoto] + photoHeight
             columnToPlacePhoto = columnToPlacePhoto < (numberOfColumns - 1) ? (columnToPlacePhoto + 1) : 0
         }
     }


     //
     override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {

         let layoutAttributes = super.layoutAttributesForElements(in: rect)

         layoutAttributes?.forEach({ (attribute) in
             // I did this to keep attribute of Collection View Header, without this step, my Header doesn't show up
             if attribute.representedElementKind == UICollectionView.elementKindSectionHeader{
                 cache.append(attribute)
             }})
         return cache
     }
}

I assign my layout to Collection View

class ProfileVC: UICollectionViewController, UICollectionViewDelegateFlowLayout, {

    override func viewDidLoad() {
        super.viewDidLoad()

        let layout = MyLayout()
        layout.delegate = self
        self.collectionView.collectionViewLayout = layout
        self.collectionView.isScrollEnabled = true
}

I also set the number of items, number of sections, size of header and so on.

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return posts.count
    }

    // Set size of header
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return CGSize(width: view.frame.width, height: 190)
    }

    // Set cell
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ProfilePostCell
        cell.post = posts[indexPath.item]
        return cell
    }

I am pretty sure my original Collection View works well enter image description here

But after I add the following, it can not scroll. Please help me out of here, thanks in advance.

let layout = MyLayout()
        layout.delegate = self
        self.collectionView.collectionViewLayout = layout
        self.collectionView.isScrollEnabled = true
1
can you put that code. on viewWillappear() and see what happens.Eddwin Paz
Nothing changes.Sheldon TT

1 Answers

0
votes

I have solved this problem by adding.

contentHeight = max(contentHeight, frame.maxY)