完全に理解する Storyboard & UIKit (Day 17): UICollectionViewの実装基礎
S7r1n9y
Engineer
このシリーズの記事一覧
- 1. 完全に理解する Storyboard & UIKit (Day 1): 基礎概念と歴史
- 2. 完全に理解する Storyboard & UIKit (Day 2): XcodeでのStoryboardの基本操作
- 3. 完全に理解する Storyboard & UIKit (Day 3): UIViewControllerのライフサイクル
- 4. 完全に理解する Storyboard & UIKit (Day 4): Auto Layoutの基本原理
- 5. 完全に理解する Storyboard & UIKit (Day 5): Auto Layoutの複雑な制約の解決
- 6. 完全に理解する Storyboard & UIKit (Day 6): UIStackViewを使った効率的なレイアウト設計
- 7. 完全に理解する Storyboard & UIKit (Day 7): Size Classesによるレスポンシブデザイン
- 8. 完全に理解する Storyboard & UIKit (Day 8): Segueによる画面遷移とデータ渡し
- 9. 完全に理解する Storyboard & UIKit (Day 9): Navigation Controllerの活用
- 10. 完全に理解する Storyboard & UIKit (Day 10): Tab Bar Controllerの活用
- 11. 完全に理解する Storyboard & UIKit (Day 11): 基本的なUI部品(UILabel, UIButton, UITextField)
- 12. 完全に理解する Storyboard & UIKit (Day 12): UITextViewとキーボードハンドリング
- 13. 完全に理解する Storyboard & UIKit (Day 13): UIImageViewと画像リソース管理
- 14. 完全に理解する Storyboard & UIKit (Day 14): UIScrollViewとコンテンツのスクロール
- 15. 完全に理解する Storyboard & UIKit (Day 15): UITableViewの実装基礎
- 16. 完全に理解する Storyboard & UIKit (Day 16): UITableViewのカスタムセル作成
- 17. 完全に理解する Storyboard & UIKit (Day 17): UICollectionViewの実装基礎
- 18. 完全に理解する Storyboard & UIKit (Day 18): UICollectionViewのカスタムレイアウト
- 19. 完全に理解する Storyboard & UIKit (Day 19): Custom Viewの作成とStoryboardでの利用(@IBDesignable, @IBInspectable)
- 20. 完全に理解する Storyboard & UIKit (Day 20): アニメーションの実装(UIView Animation)
- 21. 完全に理解する Storyboard & UIKit (Day 21): Gesture Recognizerによるタッチ処理
- 22. 完全に理解する Storyboard & UIKit (Day 22): UIAlertControllerによるアラートとアクションシート
- 23. 完全に理解する Storyboard & UIKit (Day 23): UIDatePickerやUIPickerViewの実装
- 24. 完全に理解する Storyboard & UIKit (Day 24): Storyboard Referenceを用いたStoryboard分割
- 25. 完全に理解する Storyboard & UIKit (Day 25): XIBとStoryboardの使い分け・併用
- 26. 完全に理解する Storyboard & UIKit (Day 26): UIAppearanceによるアプリ全体の色・スタイル管理
- 27. 完全に理解する Storyboard & UIKit (Day 27): ダークモード対応とアセットカタログ
- 28. 完全に理解する Storyboard & UIKit (Day 28): Accessibility(VoiceOver対応など)のUI設計
- 29. 完全に理解する Storyboard & UIKit (Day 29): UIKitからSwiftUIへの移行 / UIKitでのSwiftUI利用
- 30. 完全に理解する Storyboard & UIKit (Day 30): 実践:1つのアプリをStoryboardとUIKitで完成させる
Sponsored
完全に理解する Storyboard & UIKit (Day 17): UICollectionViewの実装基礎
UITableViewは「1列で縦に並ぶ」リストでした。しかし、iPhoneの「写真」アプリのように、画像が3列〜4列のタイル状(グリッド)に並ぶUIを作りたい場合はどうすれば良いでしょうか?
そこで登場するのが、TableViewの進化系であり兄弟とも言えるコンポーネント、UICollectionView です。
1. UICollectionViewとは?
UICollectionView は、データの集合(コレクション)を、カスタム可能なレイアウトで画面上に配置・スクロールさせるためのビューです。
UITableViewと基礎概念は全く同じ(DataSourceとDelegateプロトコルを使う)ですが、最大的な違いは 「レイアウトの決定権を別のオブジェクト(レイアウトオブジェクト)が持っている」 という点です。これにより、縦横のグリッドだけでなく、円形レイアウトやPinterestのような複雑な配置も可能になります。
2. Storyboard上の準備とセル作成
設定方法はUITableViewとほぼ同じです。
- ViewControllerのキャンバス内に Collection View を配置し、四方に制約をつけます。
- 配置した Collection View の中にある四角いマス目、Collection View Cell を選択します。(※UITableViewCellとは異なります)
- このマスの中に、
UIImageViewやUILabelを配置し、制約をつけます。 - Attributes Inspectorで、Cellに
Identifier(例:PhotoCell)を設定します。 - View Controllerに接続する専用のクラスファイル(
UICollectionViewCellのサブクラス)を作成し、Storyboard上でCustom Classとして指定します。 IBOutletを接続します(Collection View自体と、Cell内の画像など)。
3. 実装の3ステップ
UITableViewと瓜二つなので、前々回の復習を兼ねて見ていきましょう。
ステップ1: プロトコルに準拠する
swiftclass ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { @IBOutlet weak var collectionView: UICollectionView! let photos = ["cat1", "cat2", "cat3", "cat4", "cat5"] // アセット名 // ...
ステップ2: 委譲先(自分自身)を登録する
swiftoverride func viewDidLoad() { super.viewDidLoad() collectionView.dataSource = self collectionView.delegate = self }
ステップ3: 必須メソッドを実装する
swift// ① 表示するアイテムの総数 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return photos.count } // ② 各マスのセルの構築 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UICollectionViewCell() } let imageName = photos[indexPath.item] // TableViewのrowではなくitemを使います cell.imageView.image = UIImage(named: imageName) return cell }
これでデータとセルは結びつきました!しかし、この状態で実行してもおそらく意図した通りの3列並びにはなりません。マスのサイズがバラバラだったり、1列になったりします。
なぜなら、CollectionViewにおけるセルのサイズは、UITableViewとは違って開発者が明示的にサイズ計算ロジック(レイアウト)を提供しなければならない からです。
4. UICollectionViewFlowLayout の基礎
最も標準的でよく使われるレイアウトクラスが UICollectionViewFlowLayout です。これは要素を「左から右へ、端まで行ったら次の行へ」と並べる(フローさせる)レイアウトを提供します。
サイズの指定は、もう一つのプロトコル UICollectionViewDelegateFlowLayout を使って行います。
swift// プロトコルを追加 extension ViewController: UICollectionViewDelegateFlowLayout { // ③ セルのサイズを返すメソッド(超重要) func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { // 画面幅を3等分して、1辺の長さを決める(隙間を持たせたい場合はその分の数値を引く) let width = collectionView.frame.width / 3.0 return CGSize(width: width, height: width) // 正方形のマスにする } // セル同士の縦の隙間(行間) func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return 0 } // セル同士の横の隙間(列間) func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat { return 0 } }
この計算コードを追加することで、はじめてInstagramのプロフィール画面のような「完璧な3列の正方形グリッド」が完成します。
📝 今日のまとめ
- UICollectionView は、データをタイル(グリッド)状に並べるためのコンポーネント。
- DataSourceとDelegateの考え方はUITableViewと全く同じ。行は
rowではなくitemと呼ぶ。 - 最大の違いはレイアウトの概念。標準では
UICollectionViewFlowLayoutが使われる。 UICollectionViewDelegateFlowLayoutプロトコルを使い、sizeForItemAtメソッドを実装してマスのサイズを計算・指定する必要がある。
これでグリッドレイアウトの基礎が完成しました。 しかし、AppleはiOS 13/14でCollectionViewのレイアウトエンジンを根本から刷新し、より直感的で恐ろしいほど強力なシステムを導入しました。 明日の Day 18 では、現代のiOS開発の主流となっている UICollectionView Compositional Layout に挑戦します。
このシリーズの記事一覧
- 1. 完全に理解する Storyboard & UIKit (Day 1): 基礎概念と歴史
- 2. 完全に理解する Storyboard & UIKit (Day 2): XcodeでのStoryboardの基本操作
- 3. 完全に理解する Storyboard & UIKit (Day 3): UIViewControllerのライフサイクル
- 4. 完全に理解する Storyboard & UIKit (Day 4): Auto Layoutの基本原理
- 5. 完全に理解する Storyboard & UIKit (Day 5): Auto Layoutの複雑な制約の解決
- 6. 完全に理解する Storyboard & UIKit (Day 6): UIStackViewを使った効率的なレイアウト設計
- 7. 完全に理解する Storyboard & UIKit (Day 7): Size Classesによるレスポンシブデザイン
- 8. 完全に理解する Storyboard & UIKit (Day 8): Segueによる画面遷移とデータ渡し
- 9. 完全に理解する Storyboard & UIKit (Day 9): Navigation Controllerの活用
- 10. 完全に理解する Storyboard & UIKit (Day 10): Tab Bar Controllerの活用
- 11. 完全に理解する Storyboard & UIKit (Day 11): 基本的なUI部品(UILabel, UIButton, UITextField)
- 12. 完全に理解する Storyboard & UIKit (Day 12): UITextViewとキーボードハンドリング
- 13. 完全に理解する Storyboard & UIKit (Day 13): UIImageViewと画像リソース管理
- 14. 完全に理解する Storyboard & UIKit (Day 14): UIScrollViewとコンテンツのスクロール
- 15. 完全に理解する Storyboard & UIKit (Day 15): UITableViewの実装基礎
- 16. 完全に理解する Storyboard & UIKit (Day 16): UITableViewのカスタムセル作成
- 17. 完全に理解する Storyboard & UIKit (Day 17): UICollectionViewの実装基礎
- 18. 完全に理解する Storyboard & UIKit (Day 18): UICollectionViewのカスタムレイアウト
- 19. 完全に理解する Storyboard & UIKit (Day 19): Custom Viewの作成とStoryboardでの利用(@IBDesignable, @IBInspectable)
- 20. 完全に理解する Storyboard & UIKit (Day 20): アニメーションの実装(UIView Animation)
- 21. 完全に理解する Storyboard & UIKit (Day 21): Gesture Recognizerによるタッチ処理
- 22. 完全に理解する Storyboard & UIKit (Day 22): UIAlertControllerによるアラートとアクションシート
- 23. 完全に理解する Storyboard & UIKit (Day 23): UIDatePickerやUIPickerViewの実装
- 24. 完全に理解する Storyboard & UIKit (Day 24): Storyboard Referenceを用いたStoryboard分割
- 25. 完全に理解する Storyboard & UIKit (Day 25): XIBとStoryboardの使い分け・併用
- 26. 完全に理解する Storyboard & UIKit (Day 26): UIAppearanceによるアプリ全体の色・スタイル管理
- 27. 完全に理解する Storyboard & UIKit (Day 27): ダークモード対応とアセットカタログ
- 28. 完全に理解する Storyboard & UIKit (Day 28): Accessibility(VoiceOver対応など)のUI設計
- 29. 完全に理解する Storyboard & UIKit (Day 29): UIKitからSwiftUIへの移行 / UIKitでのSwiftUI利用
- 30. 完全に理解する Storyboard & UIKit (Day 30): 実践:1つのアプリをStoryboardとUIKitで完成させる