Swift4にPageMenuを導入&モーダル遷移

# Swift4に[PageMenu](https://github.com/PageMenu/PageMenu)の導入
PageMenuとは、下の画像の赤枠の部分のことを言います。
![スクリーンショット 2019-09-19 11.27.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332582/2c65e4dd-bfe9-5919-f558-fade237d5dea.png)

## CocoaPodsで導入
PageMenuは、CocoaPodsに対応しているので、Podfileに下記を追加

```Podfile
pod 'PageMenu'
```
installする。

```
$ pod install
```

### Could not build Objective-C module 'PageMenu'
エラーが出た。Objective-Cで書かれているmoduleはビルドできないらしい。
>Could not build Objective-C module 'PageMenu'

[似たようなエラー](https://pippi-pro.com/swift-could-not-build-objective-c-module)で困っている方がいたので、それの解法と同じようにやってみたのですが、同じエラーが表示されてしまった。

どうやら、Swift3以前のものがCocoapodsでは使用されていて、Swfit4にPageMenuというライブラリはCocoaPodsでは入れることができないらしい(?)。
よって、ソースコードを手動で組み込む。

## githubからソースコードを取ってくる
[こちら](https://github.com/PageMenu/PageMenu/tree/master/Classes)から、CAPSPageMenu.swiftをプロジェクトに入れれば良い。

### Type 'NSNotification.Name' has no member 'UIDevice'
>Type 'NSNotification.Name' has no member 'UIDevice'

みたいなエラーが出た場合は、エラー個所を以下のように修正する。

```
(-) NSNotification.Name.UIDeviceOrientationDidChange
(+) UIDevice.orientationDidChangeNotification
```
[参考](https://qiita.com/okyawa/items/4b4b06d6a1336d9e86e2)

### 正常に動いたソースコード
```ViewController.swift
  override func viewDidLoad() {
    super.viewDidLoad()
    edgesForExtendedLayout = []//navigation barをつけている場合は、navigation bar とviewが被らないように
    self.title = "test"
    self.navigationController?.navigationBar.backgroundColor = .cyan
    
    //MainStoryboardのViewControllerを取得
    let vc1 = storyboard?.instantiateViewController(withIdentifier: "testViewController") as! TestViewController
    let vc2 = storyboard?.instantiateViewController(withIdentifier: "test2ViewController") as! Test2ViewController
    let vc3 = storyboard?.instantiateViewController(withIdentifier: "testViewController") as! TestViewController
    _ = vc1.view
    _ = vc2.view
    _ = vc3.view
    vc1.title = "1"
    vc2.title = "2"
    vc3.title = "3"
    
    //パラメーターに関しては、github参照
    let parameters: [CAPSPageMenuOption] = [
      .menuItemSeparatorWidth(4.0),
      .useMenuLikeSegmentedControl(true),
      .menuItemSeparatorPercentageHeight(0.0)
    ]
    pageMenu = CAPSPageMenu(viewControllers: [vc1, vc2, vc3], frame: view.bounds, pageMenuOptions: parameters)
    view.addSubview(pageMenu!.view)
  }
```

# PageMenu使用時に、モーダル遷移で画面を戻ると、Navigation barの下にPageMenuが隠れてしまう
## PageMenuで追加されているView(Controller)では、self.navigationControllerが使えない。
ExampleViewControllerから、ResultViewControllerにモーダル遷移したい。この時、ResultViewControllerはExampleViewControllerとは別のstoryboardにあり、ResultViewControllerに紐づけられているNavigationControllerのidentityは、"Result_initial"となっている。
(修正前のコード)

```ExampleViewController.swift
let storyboard: UIStoryboard = UIStoryboard(name: "Result", bundle: nil)
let next = storyboard.instantiateViewController(withIdentifier: "Result_initial") as! UINavigationController
present(next, animated: true, completion: nil)
```
これでは、モーダル遷移できるが、遷移先のResultViewController.swiftで以下のようにモーダル遷移を定めてページを戻すように設定して、ページを戻った時に、Navigation barの下にPageMenuが隠れてしまう。

```ResultViewController.swift
private extension UIViewController{
  @IBAction func backToStoryboard(_ sender: Any) {
    self.dismiss(animated: true, completion: nil)
  }
}
```
調べたところ、このような場合は、page遷移の仕方に問題があるらしい。

```ExampleViewController.swift
(-)let storyboard: UIStoryboard = UIStoryboard(name: "Result", bundle: nil)
(-)let next = storyboard.instantiateViewController(withIdentifier: "Result_initial") as! UINavigationController
(-)present(next, animated: true, completion: nil)

(+)var modalView = UINavigationController(rootViewController: NextView()) 
(+)modalView.modalTransitionStyle = UIModalTransitionStyle.CoverVertical 
(+)self.view.window?.rootViewController!.presentViewController(modalView, animated: true, completion: nil)
```
このように変更を加えたところ、pageは遷移するが、遷移先の画面が真っ黒になってしまう。
これは、遷移先のViewControllerは指定されているが、Storyboardが指定されていないために起こってしまった。
よって、以下のように変更すれば、最初の想定通りの動作を得ることができる。

```ExampleViewController.swift
(-)var modalView = UINavigationController(rootViewController: NextView()) 
(-)modalView.modalTransitionStyle = UIModalTransitionStyle.CoverVertical 
(-)self.view.window?.rootViewController!.presentViewController(modalView, animated: true, completion: nil)

(+)let resultViewController = UIStoryboard(name: "Result", bundle: nil).instantiateInitialViewController() as! UIViewController
(+)self.view.window?.rootViewController!.present(resultViewController, animated: true, completion: nil)
```

## 参考
- PageMenuの他にも、上のMenubar(?)の種類はあるらしいです。  
[SmartNewsのようなUIを実現するライブラリ3つを比較してみた](http://animane.hatenablog.com/entry/2015/09/27/133859)
- [化粧品アプリLIPSでも使われてるPageMenuを導入方法[Swift3][Swift4でも]](https://qiita.com/hi_erica_/items/7334192299e84a4fa069)
- [SwiftライブラリPageMenu使用時、self.navigationController?.pushViewControllerによる画面遷移ができない](https://ja.stackoverflow.com/questions/16458/swift%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AApagemenu%E4%BD%BF%E7%94%A8%E6%99%82-self-navigationcontroller-pushviewcontroller%E3%81%AB%E3%82%88%E3%82%8B%E7%94%BB%E9%9D%A2%E9%81%B7%E7%A7%BB%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84)
- [セグエを使わない画面遷移時の次画面が黒くなる](https://ja.stackoverflow.com/questions/4383/セグエを使わない画面遷移時の次画面が黒くなる)