タブごとにStoryboardを分割する

More than 5 years have passed since last update.

@hedjirog です。Interface Builder や Storyboard は必要に応じて使いたい派です。

今回は UITabBarController で複数のタブを保持する際、タブごとに Storyboard を分割する方法 を紹介します。

UITabBarController で複数のタブを保持する際に、 必ず Storyboard を分割することを推奨するものではありません。 状況に応じて Storyboard の分割を検討してください。

ソースコードは GitHub からダウンロードできます。


手順

4つのタブ (Home, Connect, Discover, Me) を持つアプリケーションの開発を想定し、タブごとに Storyboard を分割することを考えます。

アプリケーションのルートの View Controller はコードから生成し、各タブの View Controller は UITabBarController の初期化時に分割した Storyboard から生成します。

以下、手順の説明です。


1. 複数の Storyboard の生成

まずは4つの Storyboard を作成します。

ここでは Home, Connect, Discover, Me という4つの Storyboardを作成してみます。

storyboards.png


2. UITabBarItem の配置

それぞれの Storyboard の Initial View Controller で、UITabBarItem を配置します。

ここでは Storyboard の Initial View Controller を Navigation Controller とし、そこに UITabBarItem を配置してみます。

tabbaritems.png


3. UIStoryboard のカテゴリーによる拡張(必要に応じて)

分割した Storyboard をコードで扱いやすいようにカテゴリーによる UIStoryboard クラスの拡張をしましょう。これは必須ではありません。好みや必要に応じて実装してください。

ここでは MSDExtensions という UIStoryboard のカテゴリーを定義してみます。


UIStoryboard+MSDExtensions.h

#import <UIKit/UIKit.h>


@interface UIStoryboard (MSDExtensions)

+ (instancetype)msd_homeStoryboard;
+ (instancetype)msd_connectStoryboard;
+ (instancetype)msd_discoverStoryboard;
+ (instancetype)msd_meStoryboard;

@end



UIStoryboard+MSDExtensions.m

#import "UIStoryboard+MSDExtensions.h"


NSString * const kHomeName = @"Home";
NSString * const kConnectName = @"Connect";
NSString * const kDiscoverName = @"Discover";
NSString * const kMeName = @"Me";

@implementation UIStoryboard (MSDExtensions)

+ (instancetype)msd_homeStoryboard
{
return [self msd_storyboardWithName:kHomeName];
}

+ (instancetype)msd_connectStoryboard
{
return [self msd_storyboardWithName:kConnectName];
}

+ (instancetype)msd_discoverStoryboard
{
return [self msd_storyboardWithName:kDiscoverName];
}

+ (instancetype)msd_meStoryboard
{
return [self msd_storyboardWithName:kMeName];
}

+ (instancetype)msd_storyboardWithName:(NSString *)name
{
return [self storyboardWithName:name bundle:nil];
}

@end



4. アプリケーション特有の UITabBarController のサブクラスの定義

UITabBarController を継承したクラスを定義して、アプリケーション特有の処理を定義しやすくします。

ここでは MSDTabBarController というサブクラスを定義してみます。


MSDTabBarController.h

#import <UIKit/UIKit.h>


@interface MSDTabBarController : UITabBarController

@end



5. ルートの View Controller の生成

App Delegate の application:didFinishLaunchingWithOptions: メソッドでルートの View Controller を設定します。

Window の rootViewController プロパティに対して、先ほど定義した MSDTabBarController クラスのインスタンスをセットしましょう。


MSDAppDelegate.m

#import "MSDAppDelegate.h"

#import "MSDTabBarController.h"

@implementation MSDAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = [[MSDTabBarController alloc] init];
[self.window makeKeyAndVisible];

return YES;
}

@end



6. 各タブの View Controller の生成

MSDTabBarController の初期化処理時に、各タブに保持される View Controller を Storyboard から生成します。

ここでは viewDidLoad メソッドが呼ばれるタイミングで、viewControllers プロパティの配列を適切に変更するようにしてみます。


MSDTabBarController.m

#import "MSDTabBarController.h"

#import "UIStoryboard+MSDExtensions.h"

@implementation MSDTabBarController

- (void)viewDidLoad
{
[super viewDidLoad];

[self setUpViewControllers];
}

- (void)setUpViewControllers
{
self.viewControllers = @[[[UIStoryboard msd_homeStoryboard] instantiateInitialViewController],
[[UIStoryboard msd_connectStoryboard] instantiateInitialViewController],
[[UIStoryboard msd_discoverStoryboard] instantiateInitialViewController],
[[UIStoryboard msd_meStoryboard] instantiateInitialViewController]
];
}

@end



まとめ

UITabBarController で複数のタブを扱う場合に、タブごとに Storyboard を分割する方法を紹介しました。

複数の Storyboard を扱う方法は、すでに Developers.IO の記事 でも紹介されています。

該当記事ではメインの画面遷移と共通の画面遷移のために Storyboard を作成する方法であるのに対し、ここでは メインの画面遷移のために Storyboard は作成せず、(タブごとの)独立した複数の Storyboard を作成してコードから呼び出す方法 であるという点で異なります。

UITabBarController を利用しつつ Storyboard を分割する際は、両者を比較し、開発しているアプリケーションにより相応しい方法を選択してください。


関連リンク