LoginSignup
3
2

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-09-19

Swift4にPageMenuの導入

PageMenuとは、下の画像の赤枠の部分のことを言います。
スクリーンショット 2019-09-19 11.27.36.png

CocoaPodsで導入

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

pod 'PageMenu'

installする。

$ pod install

Could not build Objective-C module 'PageMenu'

エラーが出た。Objective-Cで書かれているmoduleはビルドできないらしい。

Could not build Objective-C module 'PageMenu'

似たようなエラーで困っている方がいたので、それの解法と同じようにやってみたのですが、同じエラーが表示されてしまった。

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

githubからソースコードを取ってくる

こちらから、CAPSPageMenu.swiftをプロジェクトに入れれば良い。

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

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

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

(-) NSNotification.Name.UIDeviceOrientationDidChange
(+) UIDevice.orientationDidChangeNotification

参考

正常に動いたソースコード

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)

参考

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2