螺旋のCollectionViewを作ってみる

# 概要

[CollectionViewプログラミングガイド2014](https://developer.apple.com/jp/documentation/CollectionViewPGforIOS.pdf)
に


> iOSのコレクションビューは、単に行と列の形に並べる以外にもさまざまな配置が可能です。視覚的要素のレイアウトを細かく定義することも、サブクラスを定義して必要な処理を実装することにより可能で、しかもそのレイアウトは動的に変更できます。格子、スタック、円状レイアウト、動的に変化するレイアウトその他、およそ想像できる配置は何でも実装できると言ってよいでしょう。



と書かれていたので、螺旋も描けるのかと考えCellを螺旋状に並べるCollectionViewを作りました。

# 結果
<img width="300" alt="iPhone XR" src="https://qiita-image-store.s3.amazonaws.com/0/199256/2e1a0aa2-b18c-a54b-8f4a-111239d76c2d.png">



## 作りかた
Collection Viewの柔軟なレイアウトを作るにはUICollectionViewLayoutを利用します。




### Layoutクラスを作ります

```swift

import UIKit

class CircleCollectionViewLayout: UICollectionViewLayout {
    var maxHeight: CGFloat = 0.0 //セルの高さ

    private var layoutData = [UICollectionViewLayoutAttributes]()

    /// 描画したいサイズ
    override var collectionViewContentSize: CGSize {
        return CGSize(width: collectionView!.bounds.width, height: maxHeight)
    }
    
    /// 最初に一回だけ呼ばれる
    override func prepare() {
        
        // 横の描画領域
        let allWidth = collectionView!.bounds.width - collectionView!.contentInset.left - collectionView!.contentInset.right
        
        // 半径
        let radius: CGFloat = (allWidth - 100.0) / 2
        // 20は螺旋一周でのcellの数
        let rotation = Float.pi * 2.0 / 20.0
        // 画面の真ん中のx座標
        let cx: CGFloat = collectionView!.bounds.width / 2
        
        // 螺旋頑張って書いてる
        for count in 0 ..< collectionView!.numberOfItems(inSection: 0) {
            let r = rotation * Float(count) // 角度
            let x: CGFloat = cx + radius * CGFloat(cos(r)) - 15
            let y: CGFloat = 100 + CGFloat(rotation * Float(count) * 50.0) - 15
            let attributes = UICollectionViewLayoutAttributes(forCellWith: IndexPath(item: count, section: 0))
            attributes.frame = CGRect(x:x, y:y, width:30, height: 30)
            layoutData.append(attributes)
            maxHeight = y + 100.0
        }
    }
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return layoutData
    }
}
```


### StoryboardのCollectionViewの`LayoutをCustom`にして、ClassにCustomクラスを設定します。
<img width="500" alt="スクリーンショット 2018-10-24 14.49.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/199256/a0df2ef4-795e-276f-de3a-ab24a746397a.png">



### ViewControllerのクラスを作って、StoryboardのViewControllerに割り当てます。


```swift

import UIKit

class CollectionViewController: UICollectionViewController {

    let reuseIdentifier = "CollectionViewCell"
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }


    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 100
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        return collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) 
    }
    
    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print(indexPath)
    }
}

```


以上!