見出し画像

【Swift5】SideMenuライブラリで作ったサイドメニューがいい感じに動くので紹介したい【Xcode12】


画像1

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


いいなと思ったら応援しよう!