Swift で作っているiOS アプリに、Facebook の iPhone アプリのような横にスライドして表示されるメニューを追加したいと思いました。
いくつかライブラリを見てみたところ、iOS-Slide-Menu というライブラリが簡単に使えそうです。iOS-Slide-Menu は Swift ではなく Objective-C のライブラリですが、インストールも CocoaPods で1発なのでそれを利用することにします。ただ、素直に Readme に記載されている通りの実装をしただけではうまくいきませんでした。その理由は、
- 作っているアプリが Tab Bar インターフェースを持っている
- 各タブにそれぞれ個別の Navigation Controller が設定されている
- iOS-SlideMenu が提供する SlideNavigationController はシングルトンオブジェクト
だからです。したがって、複数の Navigation Controller にそれぞれ SlideNavigationController クラスを指定すると、複数のインスタンスを生成しようとしてエラーになってしまいます。
これは、少なくとも storyboard を使って画面設計するには、ライブラリ自体を修正するか、他のライブラリを探さないといけないかな、と困っていたんですが、Issues を眺めてたら手掛りになる情報があったので、それを元にいくつか試していると何とか解決方法が見つかりました。
複数の Navigation Controller を持った Tab Bar アプリケーションで iOS-Slide-Menu を利用する
1. SlideNavigationController の設定
SlideNavigationController は window のメインの ViewController に設定します。つまり、storyboard 上で、最初に表示する画面のクラスを SlideNavigationController に設定します。
2. UITabBarController のサブクラスの作成
UITabBarController を継承したカスタムクラスを作成し、storyboard 上で、そのクラスを指定した Tab Bar Controller の画面のクラスを、「1.」 のSlideNavigationController の root view controller に設定します。
3. AppDelegate に iOS-Slide-Menuの設定をする
以下のコードを AppDelegate の didFinishLaunchingWithOptions
に書きます。今回は右からのスライドメニューしか使わないので、rightMenu
のみ設定しています。
//iOS-Slide-Menu
let slideMenuTableViewController = SlideMenuTableViewController()
SlideNavigationController.sharedInstance().rightMenu = slideMenuTableViewController;
4. UITabBarController のサブクラスに iOS-Slide-Menu に必要なメソッドを実装する
「2.」 で作成した UITabBarController のサブクラスに以下のメソッドを実装します。Navigation Controller ではなく、このように Tab Bar Controller に設定しないと動作しません。
func slideNavigationControllerShouldDisplayRightMenu() -> Bool {
return true
}
5. SlideNavigationController の Navigation Bar を非表示にする
このままでは、SlideNavigationController の Navigation Bar が表示されている状態になるので、各タブの Navigation Controller の Navigation Bar が機能しません。したがって、storybord 上で「Shows Navigation Bar」のチェックを外し、SlideNavigationController の Navigation Bar を非表示にします。
6. スライドメニュー表示用のボタンとメソッドを実装する
「5.」 で Navigation Bar を非表示にしたので、スライドメニューを表示 (および非表示) するためのボタンとメソッドを自前で実装する必要があります。各タブに Bar Button Item を追加して、IBAction にスライドメニューのトグル用のメソッドを追加します。SlideNavigationController はシングルトンオブジェクトとして作られているので、sharedInstance()
でアクセスします。
@IBAction func toggleRightSlideMenu(sender: AnyObject) {
SlideNavigationController.sharedInstance().toggleRightMenu()
}
これで、複数の Navigation Controller を持った Tab Bar アプリケーションで iOS-Slide-Menu を利用することができました。