ECSlidingViewControllerを使ってみた

iOSアプリで横からスライドさせてメニューを表示する画面を実装したくて「ECSlidingViewController」というライブラリを使って実装してみた(´ω`)

ダウンロードはこちらから
ECSlidingViewController/ECSlidingViewController · GitHub

ECSlidingViewControllerのバージョンについて

インストールした中から「ECSlidingViewController」フォルダをプロジェクト内にコピーして使用します。importするファイルはこれだけ↓

#import "ECSlidingViewController.h"


ECSlidingViewControllerの使い方を検索して実際に実装してみると、これだけimportすればうまくいくはずなんだけど(実装ファイルとか正しく書けば)、なぜか一部分でエラーが表示されてしまう。

例えば

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    // slidingViewControllerとunderLeftViewControllerがエラーになる
    if (![self.slidingViewController.underLeftViewController isKindOfClass:[MenuViewController class]]) {
        self.slidingViewController.underLeftViewController  = [self.storyboard instantiateViewControllerWithIdentifier:@"Menu"];
    }
}

こんな感じで、ECSlidingViewController.hをimportすれば使えるはずのプロパティが使えなかった。おそらくバージョンがあがって影響が出ているのかなと思いながら解決策を調べてみるが載ってない〜(;_;)


で、いろいろ試してみた結果、もう1つファイルを追加することでできました!

#import "ECSlidingViewController.h"
#import "UIViewController+ECSlidingViewController.h"

正しい方法なのか不明だけどエラーが消えたのでよし。

実装してみる

よくあるのは、というかわたしが見つけたのはトップ画面にBarButtonを置いてメニュー表示…みたいな感じのが多かった(´ω`)つくってみるとこんな感じ。

f:id:aki0203:20140830202258p:plain

1. storyboardでUIViewControllerを2つ、UITableViewControllerを1つ配置する
2. ルートになっている最初のViewControllerのカスタムクラスに「ECSlidingViewController」を設定する
(もしくは、ECSlidingViewControllerをサブクラスとした新しいクラスをつくる→後々のAppDelegate.mの実装が不要になる)
3. もう1つのUIViewControllerには「FirstViewController」、UITableViewControllerには「MenuViewController」というクラスを作成して設定する
4. Identity InspecterからStoryboard IDを設定する
FirstViewController→「First」、MenuViewController→「Menu」

それぞれのコード。

AppDelegate.h
#import "ECSlidingViewController.h"
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // ECSlidingViewControllerオブジェクトを取得
    ECSlidingViewController *slidingViewController = (ECSlidingViewController *)self.window.rootViewController;
    // ストーリーボードを取得
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    // topViewControllerにFirstViewControllerを指定する
    slidingViewController.topViewController = [storyboard instantiateViewControllerWithIdentifier:@"First"];
    
    return YES;
}
FirstViewController.h
@interface FirstViewController : UIViewController

// メニューボタンをタップしたとき
- (IBAction)menuButtonTapped:(id)sender;

@end
FirstViewController.m
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    
    // シャドウ
    self.view.layer.shadowOpacity = 0.5f;
    self.view.layer.shadowRadius = 5.0f;
    self.view.layer.shadowColor = [UIColor grayColor].CGColor;

    // ECSlidingViewControllerのunderLeftViewControllerにMenuViewControllerを指定する
    if (![self.slidingViewController.underLeftViewController isKindOfClass:[MenuViewController class]]) {
        self.slidingViewController.underLeftViewController  = [self.storyboard instantiateViewControllerWithIdentifier:@"Menu"];
    }
    [self.view addGestureRecognizer:self.slidingViewController.panGesture];
    [self.slidingViewController setAnchorRightRevealAmount:130.0f];
}

// メニューボタンをタップしたときに呼ばれます
- (IBAction)menuButtonTapped:(id)sender
{
    // スライド
    [self.slidingViewController anchorTopViewToRightAnimated:YES];

    // 以前は anchorTopViewTo:ECRight だったが
    // anchorTopViewToRightAnimated:YES になった(たぶんあってる)
}
MenuViewController.m

Static Cellsを使っているので、TableCellの実装メソッドをすべてコメントアウト

階層が深い場合、実装してみる

ECSlidingViewControllerを使うと、上のように簡単にスライドメニューを実装することができた(*´∀`*)
でも、タブとかNavigationControllerの階層とかがある"中"でメニューを表示したいときはどうしたらいいんやろ(というかそっちのほうが仕事で使うな…)

と思ってやってみた。

ただ、変更点はちょっとだけ(´ω`)

1. ECSlidingViewControllerをサブクラスとしたUIViewControllerを作成する(SubViewControllerとする*1
2. SubViewControllerはルートではなく、2つ目のTabBarControllerに遷移する前に配置する(画像:赤の画面)
3. FirstViewControllerにメニューを表示するための実装をする(画像:青の画面)

f:id:aki0203:20140830222651p:plain

んでここから、実際にメニューのセルを押したときに前のTabの項目に戻りたかったんだけど、これがなかなか苦労した…NavigationControllerが、便利だけど邪魔だった←

それも含めて、この深い階層の場合のはまた別でまとめることにする〜

*1:わかりやすい名前つけられなくてごめんなさい←