Chris G.
Chris G.

Reputation: 25934

UICollectionView size is wrong in sizeForItemAt on first load - after rotating it works

I have a collectionView setup as following, but in sizeForItemAt the collectionView!.frame.size is not the same as the rendered result.

Note: I am only using Constraints for the layout of the collectionView.

Any idea?

public override init(frame: CGRect){
    super.init(frame: frame)

    self.translatesAutoresizingMaskIntoConstraints = false

    let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
    layout.minimumInteritemSpacing = 0
    layout.minimumLineSpacing = 0
    layout.scrollDirection = .vertical

    self.collectionView = UICollectionView(frame: self.frame, collectionViewLayout: layout)
    self.addSubview(self.collectionView!)
    self.collectionView?.translatesAutoresizingMaskIntoConstraints = false
    self.collectionView!.delegate = self
    self.collectionView!.dataSource = self
    self.collectionView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellIdentifier")

}

public func collectionView(_ collectionView: UICollectionView,
                                   layout collectionViewLayout: UICollectionViewLayout,
                                   sizeForItemAt indexPath: IndexPath) -> CGSize {

    collectionView!.frame.size // Tot the size of the rendered collectionView, and therefore unable to give the cell the right size???
}

Upvotes: 2

Views: 1488

Answers (1)

Sparga
Sparga

Reputation: 1625

This is happening because the cell in your UICollectionView are loaded before the layout of the view controller is finished.

When using constraints and collection views, I noticed that it is unreliable to use the collection view size before the viewDidAppear(:) call.

If you want to do a grid layout relative to the screen size, you can use UIScreen.main.bounds.size in the sizeForItemAt method.

Here, your collection view seems to be a subview of a UIView subclass. So if you can't or don't want to use the screen size, you can also reload the collection view after its superview bounds changed:

override var bounds: CGRect {
        didSet {
            if oldValue != bounds {
                self.collectionView?.reloadData()
            }
        }
}

Upvotes: 5

Related Questions