【Swift5】SideMenuライブラリで作ったサイドメニューがいい感じに動くので紹介したい【Xcode12】
SideMenuライブラリで作ったサイドメニューの満足度が高かったので実装など紹介します。
実装(CocoaPods)
cocoaPodsを使っているならばPodfileに以下コードを加えて、pod install
pod 'SideMenu', '~> 6.0'
ViewController側(表示したいViewController)
その後、このようにViewControllerに記載してください。
import SideMenu
// デリゲートプロトコルを宣言しておく
protocol SettingsDelegate {
func tappedSettingsItem(indexpath: IndexPath)
}
// 宣言しておく
var menuNavigationController: SideMenuNavigationController? = nil
// viewDidLoad(:)で呼び出す
func loadSettings() {
let menuViewController = SettingsViewController()
menuViewController.delegate = self
//サイドメニューのナビゲーションコントローラを生成
menuNavigationController = SideMenuNavigationController(rootViewController: menuViewController)
//設定を追加
menuNavigationController!.settings = makeSettings()
//左,右のメニューとして追加
SideMenuManager.default.leftMenuNavigationController = menuNavigationController
//左、右スワイプジェスチャーを追加
SideMenuManager.default.addPanGestureToPresent(toView: self.view)
SideMenuManager.default.addScreenEdgePanGesturesToPresent(toView: self.view, forMenu: .left)
}
//サイドメニューの設定
private func makeSettings() -> SideMenuSettings {
var settings = SideMenuSettings()
//動作を指定
settings.presentationStyle = .menuSlideIn
//メニューの陰影度
settings.presentationStyle.onTopShadowOpacity = 10.0
//ステータスバーの透明度
settings.statusBarEndAlpha = 0
return settings
}
// 選択されたサイドバーのアイテムを取得
func tappedSettingsItem(indexpath: IndexPath) {
// Enum使ってますが indexPath.rowが0,1,2...で返ってきます。
switch indexpath.row {
case SettingsMenu.openCreateDeckRecipeSite.rawValue:
let webPage = "https://www.pokemon-card.com/deck/deck.html"
let safariVC = SFSafariViewController(url: NSURL(string: webPage)! as URL)
safariVC.modalPresentationStyle = .fullScreen
present(safariVC, animated: true, completion: nil)
case SettingsMenu.backup.rawValue:
if MFMailComposeViewController.canSendMail()==false {
showSimpleAlertView(title: nil, message: "メールアプリが開けませんでした。", ButtonText: "OK")
return
}
var mailViewController = MFMailComposeViewController()
mailViewController.mailComposeDelegate = self
var backupmsg = ""
for deckModel in self.listViewModel.deckList {
backupmsg += "デッキ名:" + deckModel.deckTitle + "\nデッキコード:" + deckModel.duckRecipeId + "\nメモ:" + deckModel.memo + "\n\n"
}
mailViewController.setMessageBody(backupmsg, isHTML: false)
present(mailViewController, animated: true, completion: nil)
default:
break
}
}
SideMenu側のクラス
import UIKit
enum SettingsMenu: Int {
case openCreateDeckRecipeSite
case backup
case _count // enumの数を取得する
static let count = _count.rawValue
}
class SettingsViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
var delegate: SettingsDelegate? = nil
override func viewDidLoad() {
super.viewDidLoad()
loadNavigationController()
loadTableView()
// Do any additional setup after loading the view.
}
func loadNavigationController() {
self.navigationController?.navigationBar.barTintColor = UIColor.rgba(red: 203, green: 86, blue: 70, alpha: 1.0)
self.navigationController?.navigationBar.tintColor = .white
self.navigationController?.navigationBar.titleTextAttributes = [
// 文字の色
.foregroundColor: UIColor.white
]
}
func loadTableView() {
self.tableView.delegate = self
self.tableView.dataSource = self
self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
extension SettingsViewController: UITableViewDelegate {
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
self.dismiss(animated: true, completion: nil)
delegate?.tappedSettingsItem(indexpath: indexPath)
}
}
extension SettingsViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return SettingsMenu.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") else {
return UITableViewCell()
}
switch indexPath.row {
case SettingsMenu.openCreateDeckRecipeSite.rawValue:
cell.textLabel?.text = "デッキレシピを1から作る"
case SettingsMenu.backup.rawValue:
cell.textLabel?.text = "バックアップ(メール)"
default:
break
}
return cell
}
}
SideMenu側のクラスは何も表示しないViewControllerでもOKで、空白を表示できますが、セルを押下してもらう方が都合がいいことも多いので、TableViewをxibファイルに置いて先程のスクショのように表示しております。
で、押下された時にサイドメニューを閉じて、呼び出したViewControllerに記載した処理を行うって感じですね。
トラブルシューティング:iPhone12のSafeArea外が表示されない。
以下を0にしてください。
//ステータスバーの透明度
settings.statusBarEndAlpha = 0