趣味プログラミングは勢いで書け!
開発環境
> xcodebuild -version Xcode 14.0 Build version 14A5229c
Xcodeはbetaだが本記事の内容はiOS16未満のAPIを使用。
モチベーション
orthogonalScrollingBehavior を使ったことがなかったので書いてみる。
できたもの
コード
import UIKit final class ViewController: UIViewController { @IBOutlet weak var collectionView: UICollectionView! { didSet { collectionView.dataSource = self collectionView.register(CustomCollectionViewCell.self, forCellWithReuseIdentifier: "customCell") collectionView.collectionViewLayout = createLayout() } } private func createLayout() -> UICollectionViewCompositionalLayout { let horizontalMargin: CGFloat = 20 let verticalMargin: CGFloat = 10 let interItemSpacing: CGFloat = 4 let horizontalItemCount: CGFloat = 3 let screenWidth = UIScreen.main.bounds.width let availableWidth = screenWidth - horizontalMargin * 2 - (horizontalItemCount - 1) * interItemSpacing let itemLength = availableWidth / horizontalItemCount // Item let itemSize = NSCollectionLayoutSize( widthDimension: .absolute(itemLength), heightDimension: .absolute(itemLength) ) let item = NSCollectionLayoutItem(layoutSize: itemSize) // Group let groupSize = NSCollectionLayoutSize( widthDimension: .absolute(screenWidth), heightDimension: .absolute(itemLength + verticalMargin * 2) ) let group = NSCollectionLayoutGroup.horizontal( layoutSize: groupSize, subitems: [item] ) group.interItemSpacing = .fixed(interItemSpacing) group.contentInsets = .init( top: 0, leading: horizontalMargin, bottom: 0, trailing: horizontalMargin ) // Section let section = NSCollectionLayoutSection(group: group) section.contentInsets = NSDirectionalEdgeInsets( top: verticalMargin, leading: 0, bottom: verticalMargin, trailing: 0 ) section.orthogonalScrollingBehavior = .groupPaging let layout = UICollectionViewCompositionalLayout(section: section) return layout } } extension ViewController: UICollectionViewDataSource { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 9 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell( withReuseIdentifier: "customCell", for: indexPath ) as? CustomCollectionViewCell else { return UICollectionViewCell() } cell.backgroundColor = { switch indexPath.row / 3 { case 0: return .systemRed case 1: return .systemBlue case 2: return .systemGreen default: return nil } }() return cell } }