Swift4にPageMenuの導入
PageMenuとは、下の画像の赤枠の部分のことを言います。
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
正常に動いたソースコード
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"となっている。
(修正前のコード)
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が隠れてしまう。
private extension UIViewController{
@IBAction func backToStoryboard(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
}
調べたところ、このような場合は、page遷移の仕方に問題があるらしい。
(-)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が指定されていないために起こってしまった。
よって、以下のように変更すれば、最初の想定通りの動作を得ることができる。
(-)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)