【Swift】SideMenuでサイドメニューを作る
どうも、ねこきち(@nekokichi1_yos2)です。
今回は多くのアプリで使われている、サイドバー/サイドメニュー、を下記のライブラリで実装します。
↓
(参考)
↓
解説
準備
まず、
- 3つのファイルを作る(メニュー表示/設定用、メニュー項目用(TableViewControllerじゃないとダメ))
- ストーリーボードで2つのビューコントローラを設置(ViewController、NavigationController)
- 各ビューコントローラのクラスとモジュールを設定
を行います。
今回の実装はストーリーボードを活用してます。
実は、SideMenuを解説してる記事のほとんどはコードでの実装なんですが、記事通りに実装しても最終的にはエラーなどが原因で無理でした。
なので、SideMenuの公式マニュアルと同じく、ストーリーボードでの実装にしました。
実装 - ViewController
先ほど追加したTableViewControllerをインスタンス化。
//サイドメニュー用のtableViewを生成 let menuViewController = TableViewController()
SideMenuのナビゲーションコントローラを生成。
rootViewControllerには、TableViewController()を持ったmenuViewControllerを指定。
//サイドメニューのナビゲーションコントローラを生成 let menuNavigationController = SideMenuNavigationController(rootViewController: menuViewController)
ナビゲーションコントローラをSideMenuのメニューとして追加。
スワイプ動作の追加も、UISwipeGestureRecognizer、を用意しなくても、SideMenu側で実装可能。
//左,右のメニューとして追加 SideMenuManager.default.leftMenuNavigationController = menuNavigationController SideMenuManager.default.rightMenuNavigationController = menuNavigationController //左、右スワイプジェスチャーを追加 SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: self.view, forMenu: .left) SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: self.view, forMenu: .right)
SideMenu側でメニューの設定を行う。
他にも色々な設定値があるが、基本的にはこれだけで十分。
//サイドメニューの設定 private func makeSettings() -> SideMenuSettings { var settings = SideMenuSettings() //動作を指定 settings.presentationStyle = .menuSlideIn //メニューの陰影度 settings.presentationStyle.onTopShadowOpacity = 1.0 //ステータスバーの透明度 settings.statusBarEndAlpha = 0 return settings }
「onTopShadowOpacity」
影を付ければ、立体感が出る。
「statusBarEndAlpha」
初期値は1で、ステータスバーが黒くなる。
実装 - TableViewController
特にSideMenu関連のコードは必要なし。
ただ、カスタムセルを登録しないと、エラーが出てしまう。
'unable to dequeue a cell with identifier cell - must register a nib or a class
for the identifier or connect a prototype cell in a storyboard'
とりあえず、登録しておくだけでOK。
tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "customcell")
ストーリーボード
「ViewController」
「NavigationController」
「RootViewController」
ソースコード
import UIKit import SideMenu class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() //サイドメニュー用のtableViewを生成 let menuViewController = TableViewController() //サイドメニューのナビゲーションコントローラを生成 let menuNavigationController = SideMenuNavigationController(rootViewController: menuViewController) //設定を追加 menuNavigationController.settings = makeSettings() //左,右のメニューとして追加 SideMenuManager.default.leftMenuNavigationController = menuNavigationController SideMenuManager.default.rightMenuNavigationController = menuNavigationController //左、右スワイプジェスチャーを追加 SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: self.view, forMenu: .left) SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: self.view, forMenu: .right) } //サイドメニューの設定 private func makeSettings() -> SideMenuSettings { var settings = SideMenuSettings() //動作を指定 settings.presentationStyle = .menuSlideIn //メニューの陰影度 settings.presentationStyle.onTopShadowOpacity = 1.0 //ステータスバーの透明度 settings.statusBarEndAlpha = 0 return settings } } let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) cell.textLabel!.text = num[indexPath.row] return cell } func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { //メインスレッドでtableViewを更新 DispatchQueue.main.async { if indexPath.row == self.num.count - 5 { self.num.append(contentsOf: self.num) tableView.reloadData() } } } }
import UIKit class TableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() tableView.separatorStyle = .none tableView.register(UINib(nibName: "TableViewCell", bundle: nil), forCellReuseIdentifier: "customcell") } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return "メニュー" } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 5 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "customcell", for: indexPath) cell.textLabel?.text = "\(indexPath.row)" cell.textLabel?.textAlignment = .center return cell } }
結果