[Swift]： UICollectionViewCompositinalLayoutの基礎1

## 1. UICollectionViewCompositinalLayoutとは  
　WWDC2019にて発表されたCollectionViewの新たなレイアウトであり、これが発表される以前はUICollectionViewFlowLayoutが頻繁に利用されていました。UICollectionViewFlowLayoutを使用することでUITableViewよりも複雑なデザインのUIを設計することができるが、cell内で複数のimageを配置、スクロールためには、CollectionViewの中にCollectionViewを適用するなど、非常に複雑なコードになってしまうという問題点がありました。(← 特に初学者である私には、ホンマにこれ大変...てか、わからんかった（泣）)

 しかし、UICollectionViewCompositionalLayout(以下、CompositinalLayoutと記す) の登場により、非常に少ないコード量で上記のようなUIであったり、他にも様々な特徴のあるUIを設計することが可能となりました。

[WWDC2019]Advances in Collection View Layoutでは、CompositinalLayoutは以下の特徴があるレイアウトであると紹介されています。

#### ・Composable (構成可能)
#### ・Flexible (柔軟性)
#### ・Fast (即効性)

たしかに私もこのLayoutをだいたい理解したときは、この3つを非常に感じたのを覚えています。

## 2. CompositinalLayoutの構成要素
CompositianlLayoutの構成要素は大きく4つ存在する。 Item、Group、Section、Layoutである。
下図にも書かれているが階層としては、Item > Group > Section > Layoutといった関係性がある。要素の大きさとしては、Item < Group < Section < Layoutとなる。
![image](https://user-images.githubusercontent.com/64912886/106734308-378adc80-6656-11eb-8e93-852a85a25695.png)
![image](https://user-images.githubusercontent.com/64912886/106735096-24c4d780-6657-11eb-8a82-889bf8db1f6c.png)(WWDC2019 Advances in Collection View Layoutより)

それぞれの要素の大きさを指定する必要があるのだが、NSCollectionLayoutSizeクラスを用いる。

## 3. NSCollectionLayoutSize
　NSNSCollectionLayoutSizeクラスは、引数としてwidthDimension、heightDimensionの２つが設定されている。つまり、widthDimension(= 幅の値)、heightDimension(= 高さの値)がItem、Group、Section、Layoutの大きさを決定すると言っても過言ではない。widthDimension、heightDimensionにはそれぞれNSCollectionLayoutDimension(= 軸の大きさを示す)に含まれる4つの要素の中から一つ選び、設定する。
・fractionalWidth
・fractionalHeight
・absolute
・estimated
![image](https://user-images.githubusercontent.com/64912886/106736575-f7792900-6658-11eb-9cc1-ae1c280ed828.png)(WWDC2019 Advances in Collection View Layoutより)
#### 3.1 fractionalWidth, fractionalHeightとは?
fractionalWidth、fractionalHeightは以下のように言い換えることができる。  
fractionalWidth: 要素の幅 = コンテナの幅の割合
fractionalWidth: 要素の高さ = コンテナの高さの割合  
※コンテナのイメージは
Item ← Group(コンテナ)
Group ← Section(コンテナ)
Section ← Layout = collectionView(コンテナ)
という感じである。

例を見ながらのほうがわかりやすいと思う。
![image](https://user-images.githubusercontent.com/64912886/106734308-378adc80-6656-11eb-8e93-852a85a25695.png)
sizeプロパティのwidthDimensionを注目すると、.fractionalWidth(1.0)がセットされている。fractionalWidth、fractionalHeightは0 ~ 1.0までの値をとり、コンテナの割合を表している。(0~1.0 = 0 % ~ 100 %)
このsizeがitemに適用されると、itemの幅はコンテナであるgroupの幅の100 %分、つまり  
itemの幅 = groupの幅  
となる。
.fractionalWidth(0.5)がセットされているときは...
![image](https://user-images.githubusercontent.com/64912886/106743334-96a21e80-6661-11eb-9fda-e8e7d5ec312b.png)
.fractionalHeight(0.3)がセットされているとは...
![image](https://user-images.githubusercontent.com/64912886/106743727-1b8d3800-6662-11eb-969e-874bc3dfea6f.png)
となる。

#### 3.2 absolute, estimatedとは?
absoluteは固定の数値を取り、estimatedは一旦数値は指定しておくが、itemがレンダリングされたときサイズがそれに合わせて変形するようになっている。

・absolute
![image](https://user-images.githubusercontent.com/64912886/110285067-0ff8ac80-8026-11eb-86d8-80d313a8482a.png)

・estimated
![image](https://user-images.githubusercontent.com/64912886/110285204-3cacc400-8026-11eb-99e6-6b58bb856b34.png)
↓
![image](https://user-images.githubusercontent.com/64912886/110285253-4f26fd80-8026-11eb-972a-c6a37eaa1d04.png)

## まとめ
 UICollectionViewCompositinalLayoutを初めて使用したときは、私は理解するのに結構時間がかかりました。しかし、一度理解すると明らかにFlowLayoutよりも使いやすく、簡単なコードで、複雑なUI設計が可能となります。UICollectionViewCompositinalLayoutには他にもBadgeであったりだとか、Header、Hooter、ページングの種類など多くの面白い特徴を持ったLayoutです。これらについては次回紹介していきたいと思います！！

今回、初めてUICollectionViewCompositinalLayoutを使用して制作したアプリをAppStoreにてリリース中です。よろしければインストール、レビューしていただければ幸いです！！😄

App Store URL : https://apps.apple.com/us/app/neal/id1550909765


￼
￼