【Swift5】レビュー機能のUIを実装する

# はじめに
本記事では、スターとコメントを用いてレビュー機能のみためを実装していきます。

## 作るもの
本記事を見れば、下記のようにスターとコメントを用いたレビュー機能のみためを実装することができます。
![PopupDialogStarAlertSample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588214/210c4691-cc88-b45e-60aa-015ea684b533.gif)

## 対象読者
- Swiftを用いてiPhoneアプリを開発したいプログラミング初心者
- レビュー機能を実装したい方

## 開発環境
- Xcode 12.3
- Swift 5

# 目次
- 実装方法
    - ライブラリのインストール（pod install）
    - `Main.storyboard`の作成
    - `RatingViewController.xib`の作成
    - コーディング
    - 関連付け
- 参考サイト

# 実装方法
では、実際に実装していきます。

## 1. ライブラリのインストール（pod install）

Podfileに下記のように記入し、2つのライブラリをインストールします。

```
pod 'PopupDialog', '~> 1.1'
pod 'Cosmos', '~> 23.0'
```

## 2. `Main.storyboard`の作成

![MainStoryboardの作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588214/9f4141da-885e-b726-f949-c172923425a3.png)

上記の画像のように、`Main.storyboard`に必要なパーツを配置します。

- スターの数を表示するための__Label__
- コメントを表示するための__Label__
- レビューを実行するための__Button__

## 3. `RatingViewController.xib`の作成

### 3. 1. `RatingViewController.xib`の完成形
以下の画像のようにUIを作っていきます。
![RatingViewController.xibファイルの作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588214/adfdfd0d-90e6-6cf3-182a-bdf506687446.png)

### 3. 2. `RatingViewController.xib`ファイルの作成
![RatingViewController.xibファイルの作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588214/35df4356-e7ea-7fe9-eab8-7224eb03c8d3.png)

### 3. 3. `RatingViewController.xib`のUIViewのSizeをFreeformに変更

![RatingViewControllerの作成手順1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588214/72757584-a419-2fc8-6350-267b5624beca.gif)

### 3. 4. `RatingViewController.xib`に必要なパーツを配置

#### 必要なパーツ
- 2つの__Label__
- コメントするための__TextField__
- スターを選択するための__UIView__（以下の画像のように__CosmosView__をClassに設定）

![RatingViewControllerの作成手順2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588214/9b0f18d1-1217-d3c7-97eb-f311ff4caacb.gif)

## 4. コーディング

### 4. 1. `ViewController.swift`のコーディング

```Swift:ViewController.swift

import UIKit
import PopupDialog

class ViewController: UIViewController {
    
    @IBOutlet weak var starLabel: UILabel!
    @IBOutlet weak var commentLabel: UILabel!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    func showCustomDialog(animated: Bool = true) {
        
        // Create a custom view controller
        let ratingVC = RatingViewController(nibName: "RatingViewController", bundle: nil)
        
        // Create the dialog
        let popup = PopupDialog(viewController: ratingVC,
                                buttonAlignment: .horizontal,
                                transitionStyle: .bounceDown,
                                tapGestureDismissal: true,
                                panGestureDismissal: false)
        
        // Create first button
        let buttonOne = CancelButton(title: "CANCEL", height: 60) {
            self.starLabel.text = "You canceled the rating dialog"
        }
        
        // Create second button
        let buttonTwo = DefaultButton(title: "RATE", height: 60) {
            self.starLabel.text = "You rated \(ratingVC.cosmosStarRating.rating) stars"
            self.commentLabel.text = ratingVC.commentTextField.text
        }
        
        // Add buttons to dialog
        popup.addButtons([buttonOne, buttonTwo])
        
        // Present dialog
        present(popup, animated: animated, completion: nil)
    }
    
    
    @IBAction func showCustomDialogTapped(_ sender: UIButton) {
        showCustomDialog()
    }
    
}
```

### 4. 2. `RatingViewController.swift`のコーディング

```Swift:RatingViewController.swift
import UIKit
import Cosmos

class RatingViewController: UIViewController {
    
    @IBOutlet weak var cosmosStarRating: CosmosView!
    @IBOutlet weak var commentTextField: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // star数のデフォルトを3.0に設定
        cosmosStarRating.rating = 3.0
        
        commentTextField.delegate = self
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(endEditing)))
    }
    
    @objc func endEditing() {
        view.endEditing(true)
    }
}

// textFieldに関する処理
extension RatingViewController: UITextFieldDelegate {
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        endEditing()
        return true
    }
}
```

## 5. 関連付け
最後に関連付けを忘れずに行いましょう。
これで完成です！

# 参考サイト
- [PopupDialogのGitHub](https://github.com/Orderella/PopupDialog)
- [CosmosのGitHub](https://github.com/evgenyneu/Cosmos)