FlexLayoutを使用してタグ一覧画面を実装してみる

#はじめに

タグリスト？どうやって作ろう？
イメージは以下スクショのようなものでどう実装しようか調べた際にFlexLayoutを見つけ実際に使ってみて簡単に実装できたので実装方法についてまとめてみました！

<img width="375" alt="IMG_9963.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/75593/fa061054-2c41-201a-378c-6705d502f7ee.jpeg">
(最近自分の調理周りを改善に力を貸してくれたアプリのTag画面から引用させていただきましたmm)

# FlexLayoutの特徴
**AutoLayout,UIStackViewと比べるとハイパフォーマンス**

<img width="944" alt="スクリーンショット 2019-01-27 17.55.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/8acf94c7-57d9-2edd-4701-10e80db36667.png">

**直感的に書ける**
一度CSSのFlexboxを触れたことはあったのも恩恵としてあったと思いますが、
どう表現したいのか(横に追加する感じで並べたい？下に追加する感じで並べたい？)が直感的にできた。
またチェインで書けるのも直感的、気持ち良さの観点から良かったです！

FlexboxとFlexLayoutでの対応表があるのも助かりました!
<img width="889" alt="スクリーンショット 2019-01-27 22.08.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/3839d76e-5cba-e095-67c6-3e2865b0c5a8.png">

[CSS FlexBoxのチートシート](https://www.webcreatorbox.com/tech/css-flexbox-cheat-sheet)

[FlexLayoutのリポジトリはこちら](https://github.com/layoutBox/FlexLayout)

# タグリストを実装していく

## イメージ

タグリストの特徴
・横に並べていく
・画面に収まらない場合は折り返す
<img width="375" alt="IMG_9963.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/9b4d7556-53cc-60ac-36dc-094e3a846ba6.png">

## Tagを表示するUIViewを配置する

Tagを表示する範囲を指定するためのUIViewを用意します。(以後このUIViewをContainerと呼びます)
以下スクショでは範囲をわかりやすくするためにContainerの背景を黄緑色にしてます。
<img width="738" alt="スクリーンショット 2019-01-27 21.54.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/2f17f2b5-ddb2-68f1-916a-bc593dc71648.png">

Storyboardで配置したTag表示用のContainerをViewControllerに紐づける
<img width="873" alt="スクリーンショット 2019-01-27 22.04.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/52411953-ebdc-84e0-51b7-f12211b55792.png">


## イメージ通りにTagを表示するロジック部分

タグリストの特徴
・横に並べていく
・Tag表示用のUIViewからはみ出る場合は折り返す
<img width="375" alt="IMG_9963.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/837040a9-f0ca-46ac-4912-234fa9a787c5.png">

**・横に並べていく**
directionにrowを指定してあげると良さそう
<img width="577" alt="スクリーンショット 2019-01-27 22.12.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/a6c57968-1eb9-aa42-6e5b-05ce4d2f630e.png">

**・Tag表示用Containerからはみ出る場合は折り返す**
wrapを指定してあげると良さそう
<img width="900" alt="スクリーンショット 2019-01-27 22.12.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/d4c9dd60-36ca-76c4-e66b-ac27a976e7f3.png">

・横に並べていく -> direction(.row)
・Tag表示用のUIViewからはみ出る場合は折り返す ->  wrap(.wrap)

**コードに起こしてみる**

```swift

    private func setupTags(_ tags: [String]) {
        self.tagContainerView.flex.direction(.row).padding(8).wrap(.wrap).define { flex in
            tags.forEach {
                let tagLabel = UILabel()
                tagLabel.text = "#\($0)"
                tagLabel.backgroundColor = UIColor.white
                tagLabel.layer.borderWidth = 1.0
                tagLabel.layer.cornerRadius = 4
                // タグ間隔のマージン指定
                flex.addItem(tagLabel).margin(8)
            }
        }
    }
```

## Tag表示用のContainerの高さ設定

Containerの高さはTagの数とTagの文字列の長さに影響されるので高さを自動で決めるように設定する

```swift

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.updateFlexLayout()
    }
    
    private func updateFlexLayout() {
        self.tagContainerView.flex.layout(mode: .adjustHeight)
    }
```

## Tagを表示させてみる
```swift
    override func viewDidLoad() {
        super.viewDidLoad()
        self.setupTags([
            "噂の人気商品",
            "発売までもう少し",
            "インスタ栄え",
            "SSS",
            "地味に知られてない",
            "トレンド商品",
            "とりあえず最前線"
        ])
    }
```

## こんな感じになりました
<img width="369" alt="スクリーンショット 2019-01-27 22.29.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/0438d727-0d6e-9cc9-0647-bc021e871d15.png">

Containerの高さを自動で調整するよう設定しているので高さもほど良い！
わかりやすく背景を黄緑にしてみました！

```swift
self.tagContainerView.flex.layout(mode: .adjustHeight)
```

<img width="371" alt="スクリーンショット 2019-01-27 22.30.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/6b15701c-6a64-1e3a-9953-da11e16577f7.png">


#おまけ

良く使うアプリでこれもFlexLayoutでいけるんじゃないか？と思い簡易的に試してみた。
とりあえずdirectionをcolumnにしたらそれっぽくなるやろえい！
![Image_from_iOS.png](https://qiita-image-store.s3.amazonaws.com/0/75593/d16d774c-d199-8135-df5a-584e4ed23267.png)

```swift
    private func updateFlexLayout() {
        self.tagContainerView.flex.layout(mode: .adjustHeight)
    }

    private func setupTags(_ tags: [String]) {
        self.tagContainerView.flex.direction(.column).define { flex in
            tags.forEach {
                let tagLabel = UILabel()
                tagLabel.text = "\($0)"
                tagLabel.backgroundColor = UIColor.white
                tagLabel.layer.borderWidth = 1.0
                tagLabel.layer.cornerRadius = 4
                flex.addItem(tagLabel).margin(8)
            }
        }
    }
```

<img width="366" alt="スクリーンショット 2019-01-27 22.46.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/d21e2484-1a92-8790-5940-f45a73ddabf4.png">

#さいごに

どうだったでしょうか？
今までなんとなく目にしてきたタグリストって意外と簡単にできそうだなって思いませんか？

今回のはデザインをしっかり当てているわけではないので`let tagLabel = UILabel()`な部分を独自のCustomView`TagLabel()`とか定義してあげると見栄えも良くなるかと思います!

FlexLayoutのREADMEが丁寧！ありがとうございます！！！

投稿して改めて気づいたQiitaさんもしっかりtag一覧ありましたね！mm
多分これはdirection(.row),wrap(.wrap)パターンだ！
　　　　　　　　　　　　↓
<img width="264" alt="スクリーンショット 2019-01-27 23.04.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/75593/6245acfe-f58f-38d6-9b7b-3f13386f11cf.png">