UICollectionViewを使うときにレイアウトなどは、xibやStoryboardから設定することが多いのではないでしょうか。
ぼくの使い方だとxibかStoryboardでの設定で十分でUICollectionLayoutのサブクラスを作ったりすることもほとんどありません。
しかし、最近CollectionViewを色々といじるアプリを作ることがあって、その中身で動的にセルのサイズを変更したい場面が出てきました。
セルのサイズは、UICollectionViewLayoutクラスが保持している情報を元にしているので、UICollectionViewDelegate / Datasourceのメソッドでは変更できません。
UITableViewとほとんど同じかと思いきやそうでもないのですね。
でも、結局UICollectionViewDelegateFlowLayoutのデリゲートメソッドで設定することができるようで、それを使います。
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
// 条件に従ってサイズを変更する。
var size = CGSizeZero()
if width / height == 1.0 {
size = CGSize(width: 44, height: 44) // Square
} else {
size = CGSize(width: 44, height: 88) // Rect
}
return size
}
このように、セルのサイズを返すことができるので、例えばセルの中にあるUILabelの内容によって、セルのサイズを変えることだって簡単です。
他にも、CollectionViewのサイズぴったりにセルの数分だけ等分して、配置するとかそういうこともできます。ちなみに、今回ぼくがやりたかったのはこれです。
一点だけ気をつけておきたいのが、これらのメソッドでセルのサイズを変更するなら、基本的にはAutoLayoutを意識しておく必要があるということです。
といっても、縦横に可変して良いデザインなのか、表示するコンテンツのサイズが固定の方が良いのか、センターにある方がよいのかとかそういうところだけ意識しておけば問題ないと思います。