Skip to content

Instantly share code, notes, and snippets.

@mrtapac
Last active April 24, 2023 13:36
Show Gist options
  • Save mrtapac/930fdc1497c7db8e73b3778e1a08295f to your computer and use it in GitHub Desktop.
Save mrtapac/930fdc1497c7db8e73b3778e1a08295f to your computer and use it in GitHub Desktop.
UICollectionViewCompositionalLayout month calendar example
//
// MonthViewController.swift
// Calendar
//
// Created by Alexander T on 22.04.2023.
//
import UIKit
// MARK: - View Controller
final class MonthViewController: UIViewController {
// MARK: - Private variables
private let days = [
[ 1, 2],
[ 3, 4, 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14, 15, 16],
[17, 18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29, 30],
[31]
]
// MARK: - Outlets
@IBOutlet private var collectionView: UICollectionView!
// MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
setupCollectionViewLayout()
}
// MARK: - Private methods
private func setupCollectionViewLayout() {
collectionView.collectionViewLayout = UICollectionViewCompositionalLayout { section, env in
let dayItemSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0 / CGFloat(self.days[section].count)),
heightDimension: .fractionalHeight(1.0)
)
let dayItem = NSCollectionLayoutItem(layoutSize: dayItemSize)
let weekGroupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(CGFloat(self.days[section].count) / 7),
heightDimension: .absolute(40.0)
)
let weekGroup = NSCollectionLayoutGroup.horizontal(
layoutSize: weekGroupSize,
subitems: [dayItem]
)
weekGroup.edgeSpacing = NSCollectionLayoutEdgeSpacing(
leading: section == .zero ? .flexible(.zero) : .fixed(.zero),
top: .fixed(.zero),
trailing: section == .zero ? .fixed(.zero) : .flexible(.zero),
bottom: .fixed(.zero)
)
return NSCollectionLayoutSection(group: weekGroup)
}
}
}
// MARK: - Day Cell
final class DayCell: UICollectionViewCell {
@IBOutlet var dayLabel: UILabel!
}
// MARK: - Collection View DataSource
extension MonthViewController: UICollectionViewDataSource {
func numberOfSections(
in collectionView: UICollectionView
) -> Int {
days.count
}
func collectionView(
_ collectionView: UICollectionView,
numberOfItemsInSection section: Int
) -> Int {
days[section].count
}
func collectionView(
_ collectionView: UICollectionView,
cellForItemAt indexPath: IndexPath
) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: "DayCell",
for: indexPath
) as? DayCell else {
return UICollectionViewCell()
}
cell.dayLabel.text = String(days[indexPath.section][indexPath.row])
return cell
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment