I figured out how to fill the view with 4 items per row with equal spacing in both landscape and portrait modes. The dimensions are properly calculated once the device starts in the portrait mode and when the device is rotated.
But weirdly when the app is launched in landscape mode it has incorrect layout (looks as if the dimensions for portrait mode were applied). Please see details in the screenshots.
Any advice?
I tried collectionView.layoutIfNeeded()
at the end of viewDidLoad
, but it didn’t help.
This is my code responsible for the layout:
import UIKit
class PhotosViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
@IBOutlet var collectionView: UICollectionView!
var store: PhotoStore!
var photoDataSource: PhotoDataSource!
// MARK: Dimentions
let topInset = CGFloat(4)
let leftInset = CGFloat(4)
let bottomInset = CGFloat(4)
let rightInset = CGFloat(4)
let minSpacing = CGFloat(4)
let numberOfItemsPerRow = CGFloat(4)
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let collectionViewWidth = collectionView.bounds.size.width
let insets = leftInset + rightInset
let spacingWidth = (numberOfItemsPerRow - 1) * minSpacing
let itemWidth = CGFloat(collectionViewWidth - insets - spacingWidth) / numberOfItemsPerRow
return CGSize(width: itemWidth, height: itemWidth)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: topInset, left: leftInset, bottom: bottomInset, right: rightInset)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return minSpacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return minSpacing
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
collectionView.collectionViewLayout.invalidateLayout()
}
Launched in landscape:
Rotated to portrait:
Rotated to landscape: