目次
前説
UIViewController の中に UIViewController を貼り付けたいことはままあると思います。
めちゃくちゃ初歩的ですが、割と細かいやり方を忘れたりするので、
テンプレートとしてこちらに残しておこうと思います。
本ポストに書いているようにStoryboard を設定し、四分割したコードをコピペすれば動くかと思います。
Stroryboard に貼っていく
UIViewController
をドラッグ&ドロップして配置し、
その中に UICollectionView
(UICollectionViewController ではない)を貼り付けます。
以下画像のような感じ。
CollectionView の制約は、親であるUIViewController の領域いっぱいいっぱいにしています。

また、UIViewController は SampleViewController というクラス名とするので、
右パネルのCustom Class にそのように設定します。

あとはコードを書いていきます。
以下4つに分けて書いていきます。
- CollectionView を使うための準備
- UICollectionViewDataSource
- UICollectionViewDelegate
- UICollectionViewDelegateFlowLayout
CollectionView を使うための準備
import UIKit
class SampleViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView
private static let cellIdentifier = "cellIdentifier"
override func viewDidLoad() {
super.viewDidLoad()
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(
UICollectionViewCell.self,
forCellWithReuseIdentifier: type(of: self).cellIdentifier
)
}
}
@IBOutlet weak var collectionView: UICollectionView
は Storyboard の UICollectionView と接続しているので忘れずに。
delegate のセットは見たままです。register(_:forCellWithReuseIdentifier:)
はUICollectionView で利用するセルを登録します。
(今回はサンプルなので、素のUICollectionViewCell を登録しています)
UICollectionViewDataSource
ここでは読んで字の如く、CollectionView のデータソースを定義します。
extension SampleViewController: UICollectionViewDataSource {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(
withReuseIdentifier: type(of: self).cellIdentifier,
for: indexPath
)
cell.backgroundColor = .blue
return cell
}
}
numberOfSections(in:)
でセクションの数を、collectionView:numberOfItemsInSection:
で各セクション中のアイテムの数を定義します。
collectionView(_:cellForItemAt:)
でどのようなセルを返すか定義します。dequeueReusableCell(withReuseIdentifier:for:)
のwithReuseIdentifier
の値には register(_:forCellWithReuseIdentifier:)
で指定したReusableIdentifier を設定します。
UICollectionViewDelegate
CollectionView でユーザーからのアクションがあったときなどに呼ばれるデリゲートメソッドを定義します。
extension SampleViewController: UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("selected \(indexPath.item)")
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
print("start scrolling")
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("scrolling")
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
print("end scrolling")
}
}
collectionView(_:didSelectItemAt:)
はセルがタップされるときに呼ばれるメソッド。
scrollViewWillBeginDragging(_:)
、scrollViewDidScroll(_:)
、scrollViewDidEndDecelerating(_:)
はそれぞれ以下のタイミングで呼ばれます。
CollectionView のスクロールが始まったとき、スクロールしている最中、スクロールの慣性がなくなって止まったとき。
UICollectionViewDelegateFlowLayout
CollectionView のレイアウトを定義します。
ちなみにこのプロトコルは上述の UICollectionViewDelegate を継承しています。
extension SampleViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(
width: collectionView.bounds.size.width,
height: 100
)
}
}
ここではセルのサイズとして、横幅いっぱい、高さ100で定義しています。
最後に
冒頭で書いた通り、Storyboard を設定して四分割したコードをコピペすれば動くかと思います!
(IBOutlet の接続は忘れずに)
分割して書き出しただけでも考えも整理された気がしました。
以上です。お疲れ様でした!
「[iOS] UIViewController の中に UICollectionView を貼り付ける」に3件のコメントがあります