Reputation: 673
My goal is to make equal spacing between the cells for the portrait and landscape orientation. I am able to do it for the portrait orientation but not for the landscape orientation. I wanted to close the gap in the landscape orientation by stretching the image width and height.
I want 2 cells per row for portrait view and 3 cells per row for landscape view.
My code is the following:
override func viewDidLoad() {
super.viewDidLoad()
if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
let itemsPerRow: CGFloat = 2
let padding: CGFloat = 5
let totalPadding = padding * (itemsPerRow - 1)
let individualPadding = totalPadding / itemsPerRow
let width = (collectionView?.frame.width)! / itemsPerRow - individualPadding
let height = width
flowLayout.itemSize = CGSize(width: width, height: height)
flowLayout.minimumInteritemSpacing = padding
flowLayout.minimumLineSpacing = padding
}
}
Upvotes: 0
Views: 1320
Reputation: 14030
Without further ado...
private var numberOfCellsPerRow: Int {
return (UIApplication.shared.statusBarOrientation == .portrait) ? 2 : 3
}
private let spacing: CGFloat = 20
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 24
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
return collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath)
}
override func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
cell.backgroundColor = .orange
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return .zero
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return spacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return spacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let availableWidth = collectionView.frame.width - CGFloat(numberOfCellsPerRow - 1) * spacing
let cellWidth = availableWidth / CGFloat(numberOfCellsPerRow)
return .init(width: cellWidth, height: cellWidth)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
collectionView.collectionViewLayout.invalidateLayout()
}
Upvotes: 0
Reputation: 2897
Try this:
override func viewDidLoad() {
super.viewDidLoad()
collectionView.backgroundColor = .white
collectionView.alwaysBounceVertical = true
collectionView.contentInsetAdjustmentBehavior = .always
collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 5
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
cell.backgroundColor = .blue
return cell
}
var spacing: CGFloat = 8
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return spacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
return spacing
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
let safeFrame = view.safeAreaLayoutGuide.layoutFrame
let size = CGSize(width: safeFrame.width, height: safeFrame.height)
return setCollectionViewItemSize(size: size)
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout {
layout.invalidateLayout()
}
}
func setCollectionViewItemSize(size: CGSize) -> CGSize {
if UIApplication.shared.statusBarOrientation.isPortrait {
let width = (size.width - 1 * spacing) / 2
return CGSize(width: width, height: width)
} else {
let width = (size.width - 2 * spacing) / 3
return CGSize(width: width, height: width)
}
}
The outcome is like this:
Upvotes: 3