Swift3でサイドメニューっぽいViewを作成する

#Swift3でサイドメニューっぽいViewを作成する

## 今回の目標
サイドメニューっぽいView(右側)を作成する。


![Qiita用サイドメニュー.png](https://qiita-image-store.s3.amazonaws.com/0/139291/33b00679-9a52-a55b-189e-ef59ee9535b7.png)

左画面のバーガーボタン等を押したら右の画面が出てきて、
グレーの背景部分をタップしたら元の画面にもどるようなものが目標です

## 開発環境
Xcode：8.2.1
言語：Swift 3
OS：MacOS

## 実装手順
1. StoryboardでViewControllerを用意する
2. サイドメニューを作成する
3. サイドメニューを呼び出す

### 1. StoryboardでViewControllerを用意する
1. StoryboardでViewControllerを2つ用意します
2. 下記画像左のViewControllerからサイドメニューにあたるViewCntrollerに「Ctrl + ドラッグ」でSegueを用意します
3. サイドメニューっぽくするためにモーダル表示にして、アニメーションを入れます(今回は以下のような設定にしています)
 - Kind：presentModally
 - Presentation：Over Current Context
 - Transition：Cross Dissolve
4. SegueにIdentifierを設定します今回は(sideMenuSegue)

<img width="1153" alt="sideメニューを作る.png" src="https://qiita-image-store.s3.amazonaws.com/0/139291/e1e98b72-d0b0-684c-3166-00e87d9f71ce.png">
 
### 2. サイドメニューを作成する
1. メニューを表示するViewと背景を表示するViewを作成する
2. 背景をタップしたときに元の画面に戻るようする
3. メニューを選択したときに元の画面に戻るようにする

#### 2-1. メニューを表示するViewと背景を表示するViewを作成する
サイドメニューを管理するViewControllerにて2つViewを定義します。
その後、2つのViewを作成する際にそれぞれの座標とサイズを指定して作成します。
このときに、メニューを表示するViewと背景を表示するViewの色を変えて作成します。

```swift:SideMenuViewController
    var sideMenuView: UITableView!
    var sideBackView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        createView()
    }

    func createView() {
        var barHeight: CGFloat!
        var displayWidth: CGFloat!
        var displayHeight: CGFloat!
        barHeight = UIApplication.shared.statusBarFrame.size.height // 表示されるステータスバーの高さを取得
        displayWidth = UIScreen.main.bounds.size.width // 表示する画面の幅を取得
        displayHeight = UIScreen.main.bounds.size.height // 表示する画面の高さを取得
        
        self.view.frame = CGRect(x:0, y:0, width:displayWidth, height:displayHeight) // 元々のViewのサイズを指定
        
        // メニューのViewを作成
        sideMenuView = UITableView(frame: CGRect(x:0, y:barHeight, width:displayWidth * 0.7, height:displayHeight - barHeight)) // CGRect(x: x座標, y: y座標, with: 横幅, height:高さ)を指定
        sideMenuView.backgroundColor = UIColor.black // 背景に黒を指定
        sideMenuView.alpha = 0.9 // 透明度を指定

        // 下記でメニューをタップしたときのためにセルのIDの指定やdelegateの指定を行っている
        sideMenuView.register(UITableViewCell.self, forCellReuseIdentifier: "SideCell")
        sideMenuView.dataSource = self
        sideMenuView.delegate = self
        sideMenuView.tableFooterView = UIView()

        view.addSubview(sideMenuView) // 作成したViewをメインのViewに追加し、表示されるようにする
        
        // 背景viewを作成
        sideBackView = UIView(frame: CGRect(x:displayWidth * 0.7, y:barHeight, width:displayWidth * 0.3, height:displayHeight - barHeight))
        sideBackView.backgroundColor = UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.5)
        view.addSubview(sideBackView)
    }

```

    
#### 2-2. 背景をタップしたときに元の画面に戻るようする
背景をタップしたときに元画面を表示するようにします。
このサイドメニューは(Storyboardで定義した通り)、モーダルで表示しているため全てのモーダル表示を閉じてしまえば元の画面に戻るということになります

```swift:SideMenuViewController

    func createView() {
/* ～ 中略 ～ */
        // 背景viewタップ時の動きを設定
        singleTap = UITapGestureRecognizer(target: self, action: #selector(SideMenuViewController.tapSingle(sender:))) // タップが行われたときに実行される関数を指定
        singleTap.numberOfTapsRequired = 1
        sideBackview.addGestureRecognizer(singleTap)
    }

    // 背景のviewをタップすると呼ばれる
    func tapSingle(sender: UITapGestureRecognizer) {
        self.dismiss(animated: true, completion: nil) // 全てのモーダルを閉じます
    }
```

#### 2-3. メニューを選択したときに元の画面に戻るようにする
メニューのViewはtableViewで作成しているので、TableViewに存在するCellが押される際に呼ばれる関数を実装し、その時にモーダル表示を閉じれば実現できます。


```swift:SideMenuViewController
    // Cellが選択された際に呼び出される.
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.dismiss(animated: true, completion: nil)
    }
```


### 3. サイドメニューを呼び出す
1. Storyboardで作成したSegueのIDを指定してサイドメニューを呼び出す

```swift:ViewController

    @IBAction func TupMenu(sender: AnyObject) {
        sideMenuCall()
    }

    func sideMenuCall() {
        self.performSegue(withIdentifier: "sideMenuSegue", sender: nil)
    }
```