LoginSignup
13
14

More than 5 years have passed since last update.

Swiftでスライドメニュー(SWRevealViewController)をStoryboardを使わず、アプリ途中から使用

Last updated at Posted at 2016-08-22

Swiftでは基本的にStoryboardを使わずにコードだけで画面も遷移も作ってます。
ナビゲーションバー上のハンバーガーボタンを押すと、横にスライドするサイドメニューが欲しくてSwiftで使えるライブラリを探した結果、今回はSWRevealViewControllerというライブラリを使わせてもらいました。
シンプルですが、綺麗なUIです。

一部実装の際にハマったので、記事として導入の流れを残しておきたいと思います。

GitHub
John-Lluch/SWRevealViewController

Storyboardを使った場合の導入チュートリアル
Creating a Sidebar Menu Using SWRevealViewController in Swift

(Facebookがこの形のメニューを最初に使ったのは知らなかった...)

1.実装したいこと

最初にログイン画面があるアプリケーションを想定しています。
ログインが完了した後のホーム画面からナビゲーションバーが設置され、そのナビゲーションバーにはスライドサイドメニューが実装されている、という構成です。

2.ライブラリの導入

冒頭に上げたチュートリアルに詳しいです。

私はCocoaPodsを用いています。
Objective-Cのライブラリなので、pod install が完了したあとに、Bridging-Header.h ファイルに下記を追記します。

#import "SWRevealViewController.h

同時に、Buid SettingのObjective-C Bridging Header 項目に下記を追記するのもお忘れなく。

$(SRCROOT)/$(PRODUCT)/Bridging-Header.h

3.Controllerの構成

必要なパーツ

  • LoginViewController...ログイン画面
  • SWRealViewController...メニューとホーム画面を接続するコントローラー(ライブラリで作られるので作成の必要なし)
  • SidebarTableViewController...メニュー用のテーブルビューコントローラー
  • NavigationController...ナビゲーション用のコントローラー(作成の必要無し)
  • HomeViewController...ホーム画面

Controllerの流れ

LoginViewControllerからSWRealViewControllerを経由して、下記の1と2が表示される。
1はメニューバーがタップされるまで2の後ろに隠れている。という構成です。

LoginViewController => SWRealViewController =>

1(rear) => SidebarTableViewController
2(front) => NavigationController => HomeViwController

4.サイドメニュー用のテーブルビュー

これもStoryboardを使わずに実装します。
ここだけでも説明すると1つのコンテンツになってしまうので、まるっとコードを載せてしまいます。
ポイントは下記かと。
- delegate, dataSource にselfを関連づけることを忘れない
- cellをregisterする

SidebarTableViewController.swift
import UIKit

class SidebarTableViewController: UIViewController,UITableViewDelegate, UITableViewDataSource {

    var tableView: UITableView  =   UITableView()
    var items: [String] = ["menu1", "menu2", "menu3"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        //テーブルビュー初期化、関連付け
        tableView.frame = UIScreen.mainScreen().bounds 
        tableView.delegate = self
        tableView.dataSource = self
        tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell")
        self.view.addSubview(tableView)
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.items.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell!
        cell.textLabel?.text = self.items[indexPath.row]
        return cell
    }

    // メニューをタップした時のアクション
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        print("セル #\(indexPath.row)!")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
};

5.ホーム画面用のController

これはラベルを1つ入れただけのホーム画面です。

if self.revealViewController() != nil のif文で、サイドメニューをターゲットにしてメニューボタンによりアクションが発生する機能を実装しています。

import UIKit

class HomeViewController: UIViewController {

    lazy private var label: UIView  = self.createLabel()
    var addBtn: UIBarButtonItem!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

         // 背景色
        self.view.backgroundColor = UIColor.whiteColor()

        // labelの設置 
         self.view.addSubview(label)

        // ナビゲーションバーの設定
        self.navigationController!.navigationBarHidden = false
        self.title = "Home"

        // ナビゲーションバー内にMenuボタンの設置
        let uiBarButtonItem : UIBarButtonItem = UIBarButtonItem(title: "Menu", style: UIBarButtonItemStyle.Plain, target: self, action: "tapBarButtonItem:")
        let uiBarButtonItems: NSArray = [uiBarButtonItem]
        self.navigationItem.setLeftBarButtonItems((uiBarButtonItems as! [UIBarButtonItem]), animated: true)

        // targetとactionを設定
        if self.revealViewController() != nil {
            uiBarButtonItem.target = self.revealViewController()
            uiBarButtonItem.action = "revealToggle:"
            self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        }
    }


    // レイアウト用のoverride
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        self.layoutLabel()
    }


    // Labelの作成
    private func createLabel() -> UIView {
        let label = UILabel(frame: CGRectZero)
        label.text = "HOME"
        return label
    }

    // Lavelのレイアウト
    private func layoutLabel() {
        label.frame = CGRectMake(0, 100, 300, 50)
        label.center.x = self.view.center.x
    }


    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

6.ホーム画面への遷移アクション

3で記載した通りのControllerの流れを、LoginViewControllerに実装します。
なんだかんだ、この部分が一番のキモだと思います。
ここの試行錯誤でハマりました...

LoginViewController.swift
func buttonAction(sender: UIButton!) {

    // HomeViewControllerとNavigationControllerをつなげる
    let homeViewController = HomeViewController()
    let navigationController = UINavigationController(rootViewController: homeViewController)

    // NavigationControllerをfront, SidebarTableViewControllerをrearにし、
    // SWRevealViewControllerに接続
    let frontViewController  = navigationController
    let rearViewController  = ()
    let swRevealVC = SWRevealViewController(rearViewController: rearViewController, frontViewController: frontViewController);
    swRevealVC.toggleAnimationType = SWRevealToggleAnimationType.EaseOut;
    swRevealVC.toggleAnimationDuration = 0.30;

    // SWRevealViewControllerに遷移する
    presentViewController(swRevealVC, animated: true, completion: nil)

}

7.完成!

ちゃんと動きました!

sidebar.gif

ここからもっとおしゃれなものにいじっていきたいと思います。

13
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14