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 にでも上げときます。
      
       
       
        - 関連記事
- UIWebView で history.back が使えないケース
- UIModalTransitionStyleCoverVertical のようなアニメーション
- iPhone でファイルの追記と上書き
- HTTPステータスを判定して UIWebView を生成する
- ローカルの html を UIWebView で表示する