View+Navigation based iOS アプリの作り方

Xcodeで iOS アプリの新規プロジェクトを作成する際、Navigation-based ApplicationやView-based Applicationといったテンプレートを選択することができますが、その両方の機能性を持たせたいということがあると思います。というか、さっきそういう境遇に陥って困ったので、メモです。

今回は、アプリのトップ画面は View-based Application だけれども、そこからメニューを選んだときには NavigationController のスタックに積んで、Navigation Bar 付きのページに遷移していくというもの。うむ、説明が難しい。平たく言うと、トップ画面は Navigation Bar がなくて、2階層目の画面は Navigation Bar があってトップに戻れる感じです。

さっそく作ります。ここでは、Sampleというアプリを考えます。

まず、View-based Application テンプレートを使ってプロジェクトを作成します。これに NavigationController の機能を追加していきます。

はじめに SampleAppDelegate.h を開いて、UINavigationController を追加します。1行追加するだけ。

@interface SampleAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    UINavigationController *navigationController;
    SampleViewController *viewController;
}

次に SampleAppDelegate.m を開いて、application:didFinishLaunchingWithOptions: と dealloc を以下のように修正します。NavigationController の rootViewController に、デフォルトの UIViewController をセットして、その view を window のサブビューに追加して表示させるようにしているのがポイントでしょうか。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    
	navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
    
    // Add the view controller's view to the window and display.
    [window addSubview:navigationController.view];
    [window makeKeyAndVisible];
    
return YES; }
- (void)dealloc { [viewController release]; [navigationController release]; [window release]; [super dealloc]; }

続いて、トップ画面では NavigationBar を隠し、2階層目以降は表示するようにします。ここでは next: が、2階層目を開く処理として、ボタンか何かに紐付けた IBAction 的なメソッドということにします。

SampleViewController.m を開いて、以下のような感じにします。

#import "SampleViewController.h"
#import "NextViewController.h"
    
@implementation SampleViewController
    
- (void)viewWillAppear:(BOOL)animated {
	self.navigationController.navigationBarHidden = YES;
}
    
- (void)hoge:(id)sender {
	NextViewController *next = [[NextViewController alloc] init];
	[self.navigationController pushViewController:next animated:YES];
 	[next release];
	self.navigationController.navigationBarHidden = NO;
}

// 以下略

ここでのポイントは、 navigationBarHidden に BOOL オブジェクトをセットするタイミングです。pushViewController:animated: する前に NavigationBar を表示しようとすると、画面遷移前ににょきっと NavigationBar が現れてくるので、あんまり心地良くありません。いろいろ試してみていただければと思いますが、コードを書く位置で、目に見える違いがあるのが GUI 開発の面白いところですね。

これで目的達成です。おつかれさまでした。大したことないですが、そのうち github にでも上げときます。

このエントリーのトラックバックURL
http://www.deftrash.com/admin/mt4/mt-tb.cgi/536