Storyboardを使わない場合のアプリケーション起動時の実装方法

さて、しばらくアプリ開発から遠ざかっていましたが、
iOS5からStoryboardという新しいUI設計ツールが導入されました。
これ、使っていますか?
従来のXIBに変わるもの、という位置づけで良いのでしょうか。
これまで、画面単位に独立したXIBファイルにて、グラフィカルにUIを定義してきましたが、
Storyboardが導入され、全画面を1ファイルで管理するようになりまいした。
利点としては、画面遷移もStoryboard上で、プログラミングレスで定義できるところでしょうか。
私はStoryboard登場以前も、InterfaceBuilderは使わない派でした。
理由としては
・InterfaceBuilderの使い方を学習するコストが高い
・使わなくてもプログラムでUIは定義できる。
・実際に開発するアプリでは、UIは単純ではなくInterfaceBuilderではやりきれない。
というのが主なものです。
とはいえ、プログラムでUI要素を1つ1つ定義していくのも、
結構大変ではありました。

では、Storyboardは、従来と比較してどれほど良くなったのでしょうか。
実際に使ってみました。
TableViewを使った一覧表示から、詳細画面に遷移する簡単なものです。
結果は、、、やっぱりしっくりきません。
従来のInterfaceBuilder同様、Storyboardもやはり学習コストが高いですね。
また各種プロパティがいくつものタブに散乱して全体が把握しにくいのは相変わらずでした。
それでも結構粘って使ってみましたが、、、結果としては使い続ける事は断念!
もっと良く理解すればきっと優れたツールなのかもしれませんが、
そのハードルを越える労力を割く気にはなりませんでした。

という訳で、Storyboardは使わずにUI構築する方法を基本から見て行く事にします。
今回はアプリを起動するまでの基本設定について、以下の手順を確認します。

1.プロジェクトを作成
  まずはXCodeでプロジェクトを新規作成します。
  アプリケーションのタイプは何でも良いですが、例としてSingleViewApplicationにします。

2.プロジェクトの設定で、Storyboardを削除
  プロジェクトの「Deployment Info」の「Main Interface」に初期設定されている値を削除します。
  初期設定では、図のようにStoryboardのファイル名が指定されています。

Main Interface 初期設定

  「Main Interface」のプルダウンの値を削除します。

Main Interface削除後

  さらに、storyboardのファイルも削除します。
  図の、Main_iPhone.storyboardとMain_iPad.storyboardを削除します。

storybord_files

3.AppDelegateにアプリ起動時の設定を追加
Storyboardを使わないので、アプリ起動時に表示するViewControllerをAppDelegate内で実装する必要があります。

Single View Application の場合のAppDelagate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	
    ViewController *vc = [[ViewController alloc] initWithNibName:nil bundle:nil];
    [self.window setRootViewController:vc];
    [self.window makeKeyAndVisible];
    return YES;
}

まず、windowのインスタンスとViewControllerのインスタンスを作成します。
そして、windowのsetRootViewControllerメソッドで初期表示するViewControllerを登録します。
setRootViewControllerは、iOS6から登場したメソッドです。
それ以前とはやり方が変わったので注意しましょう。従来のやり方のままだと、iOS6以降では回転のイベントが正しく発生しないようです。

Navigation形式のアプリケーションの場合のAppDelagate.m
以下のように、setRootViewControllerには、UINavigationControllerのインスタンスを渡します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	
    ViewController *vc = [[ViewController alloc] initWithNibName:nil bundle:nil];
    UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:vc];
    [self.window setRootViewController:navi];
    [self.window makeKeyAndVisible];
    return YES;
}
Tab形式のアプリケーションの場合のAppDelagate.m
以下のように、setRootViewControllerには、UITabBarControllerのインスタンスを渡します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.
    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
	
    ViewController *vc = [[ViewController alloc] initWithNibName:nil bundle:nil];
    UINavigationController *navi = [[UINavigationController alloc] initWithRootViewController:vc];

    UITabBarController *tab = [[UITabBarController alloc] initWithNibName:nil bundle:nil];
    [tab setViewControllers:[NSArray arrayWithObjects:navi, nil] animated:NO];
    vc.tabBarItem = [[UITabBarItem alloc] initWithTabBarSystemItem:UITabBarSystemItemMostRecent tag:10000];

    [self.window setRootViewController:tab];
    [self.window makeKeyAndVisible];
    return YES;
}

以上。

カテゴリー: Objective-c, XCode