was is invalidateLayout is not triggering sizeForItemAtIndexPath in UICollectionView? (code attached)

I can't get the column widths in this UICollectionView to resize upon a rotation change as the invalidateLayout from the custom UICollectionViewFlowLayout is NOT triggering the sizeForItemAtIndexPath method in the collectionView? Any ideas? I really just want the column resizing to occur via the sizeForItemAtIndexPath upon rotation.


**Output Code on Rotation**


Note: "sizeForItemAtIndexPath" is not triggered even though "invalidateLayout" is...

> ViewController:viewWillLayoutSubviews
> GCCalendarLayout:shouldInvalidateLayoutForBoundsChange
> GCCalendarLayout:invalidateLayout


**Custom Collection View**

    import UIKit
   
    class GCCalendar : UICollectionView, UICollectionViewDataSource, UICollectionViewDelegate {
       
        // Init ---------------
       
        func commonInit(coder aDecoder: NSCoder) {
            print("GCCalendar - commonInit")
            self.registerClass(GCCalendarCell.self, forCellWithReuseIdentifier: "GCCalendarCell")
            self.dataSource = self
            self.delegate = self
   
            let layout : GCCalendarLayout = GCCalendarLayout(coder: aDecoder)!
            self.setCollectionViewLayout(layout, animated: false)
           
            self.backgroundColor = UIColor.whiteColor()
        }
   
        required init?(coder aDecoder: NSCoder) {
            print("GCCalendar - init coder")
            super.init(coder: aDecoder)
            commonInit(coder: aDecoder)
        }
   
       
        // UICollectionViewDelegateFlowLayout ------------
       
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
            print("sizeForItemAtIndexPath")
            let w : CGFloat = floor(self.frame.size.width/7)
            return CGSize(width: w, height: w)
        }
   
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAtIndex section: Int) ->
            CGFloat {
            print("minimumInteritemSpacingForSectionAtIndex")
            return 0.0
        }
   
        func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAtIndex section: Int) -> CGFloat {
            print("minimumLineSpacingForSectionAtIndex")
            return 0.0
        }
       
       
        // UICollectionViewDataSource -------------------
       
        func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 21
        }
       
        func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCellWithReuseIdentifier("GCCalendarCell", forIndexPath: indexPath) as? GCCalendarCell
           
   
            return cell!
        }
   
   
    }


**Custom Layout**



    import UIKit
   
    class GCCalendarLayout : UICollectionViewFlowLayout {
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
       
        override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
            print("GCCalendarLayout:shouldInvalidateLayoutForBoundsChange")
            return true
        }
       
        override func invalidateLayout() {
            print("GCCalendarLayout:invalidateLayout")
            super.invalidateLayout()
           
        }
       
        override func prepareForCollectionViewUpdates(updateItems: [UICollectionViewUpdateItem]) {
            print("GCCalendarLayout:prepareForCollectionViewUpdates")
            super.prepareForCollectionViewUpdates(updateItems)
        }
   
        override func finalizeCollectionViewUpdates() {
            print("GCCalendarLayout:finalizeCollectionViewUpdates")
            super.finalizeCollectionViewUpdates()
        }

       
    }

You should invalidate the layout when orientation changes:


override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
    super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)


    collectionView.collectionViewLayout.invalidateLayout()
}

@jsslai - thanks (sorry I missed your post). I ended up using viewWillLayoutSubviews, seems to work ok (well apart from this potentially separate error I'm getting here https://forums.developer.apple.com/thread/24714)..


Is this approach OK? Any feedback welcome:


In View Controller


override func viewWillLayoutSubviews() {
     // Invalidate Layer (triggers "prepareLayout" in layout)
     self.cal.collectionViewLayout.invalidateLayout()


     // Trigger cells to redraw themselves (to get new widths etc)
     for cell in self.cal?.visibleCells() as! [GCCalendarCell] {
            cell.setNeedsDisplay()
     }
}
was is invalidateLayout is not triggering sizeForItemAtIndexPath in UICollectionView? (code attached)
 
 
Q