2012-05-03 12 views
1

したがって、アプリケーションUIWindowに固定トップバナーを設定し、複数のビューコントローラの作業ナビゲーションを実現しようとしています。私はこれを実行する他の方法があることを知っていますが、私のプロジェクト要件ではxibsを使う必要があります。アプリケーションがアクティブになった後にUIWindowサブビューが消える

:私は、バナーの下に自分自身を示すためにself.viewとself.navigationController.navigationBar.frameの両方をリサイズした各ViewControllerをviewWillAppearメソッドに続いて

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

    self.headerView = [[UIImageView alloc] init]; 
    self.headerView.frame = CGRectMake(0.0f, 20.0f, 320.0f, 44.0f); 
    self.headerView.image = [UIImage imageNamed: @"header-banner-background.png"]; 
    [self.window addSubview:self.headerView]; 

    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; 

    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.viewController]; 

    self.window.rootViewController = navigationController; 
    [self.window makeKeyAndVisible]; 
    return YES; 
} 

次のコードは、これを達成することができます

self.navigationController.navigationBar.frame = CGRectMake(0, 64, 320, 44); 
self.view.frame = CGRectMake(0, 64, 320, 396); 

これは問題なく動作します。

しかし、ユーザーがホームボタンを押すと、アプリケーションが再びアクティブになったときに、最後のViewControllerがのが表示されますが、UIWindowバナーなし、およびself.viewとnavigationBarが一番上に表示されます見て、アクティブ辞任場合。

もちろん、現在のUIViewController viewWillAppearメソッドは、アプリケーションがアクティブを返すときには呼び出されませんが、別の関数にサイズ変更コードを置き、通知を通じて呼び出す場合でも機能しません。しかし、ユーザーが棒アイテムを押してナビゲーションスタック内を移動すると、すべてが再び機能し、UIWindowはheaderViewを表示します。

誰でも、アプリケーションがアクティブに戻ったときにUIWindowヘッダービューが消える理由を理解していますか?

EDIT 1:解決策はありますか?

@interface RootViewController() 
{ 
    ViewController *viewController; 
    UINavigationController *navigationController; 
} 

@end 

@implementation RootViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
     viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil]; 
     navigationController = [[UINavigationController alloc] initWithRootViewController:viewController]; 
    } 
    return self; 
} 

- (void)loadView 
{ 
    // Implement loadView to create a view hierarchy programmatically, without using a nib. 
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 88)]; 

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; 
    [imageView setImage:[UIImage imageNamed:@"header"]]; 

    [view addSubview:imageView]; 

    navigationController.navigationBar.frame = CGRectMake(0, 44, 320, 44); 

    [view addSubview:navigationController.navigationBar]; 

    self.view = view; 

} 

EDIT 2:第二の可能な解決策、まだこれはviewController1のプッシュせず、罰金だ結果、ある

- (void)loadView 
{ 
    NSLog(@"loadView root"); 

    // Implement loadView to create a view hierarchy programmatically, without using a nib. 
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 88)]; 

    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; 
    [imageView setImage:[UIImage imageNamed:@"banner"]]; 
    [view addSubview:imageView]; 

    navigationController = [[UINavigationController alloc] init]; 
    navigationController.navigationBar.frame = CGRectMake(0, 43, 320, 44); 
    [view addSubview:navigationController.navigationBar]; 

    [self addChildViewController:navigationController]; 

    self.view = view; 
    [self.view setBackgroundColor:[UIColor yellowColor]]; 
} 

を働いていません(黄色の背景からであることに注意rootViewController):代わり

Without push

これをr追加のesult:

- (void)viewDidLoad 
{ 
    viewController1 = [[ViewController1 alloc] initWithNibName:@"ViewController1" bundle:nil]; 
    [navigationController pushViewController:viewController1 animated:YES];  
} 

With PUSH

新しいビューコントローラが押されていない(背景は黒であるべきである)と、ナビゲーションバーが消えました。

EDIT 3:Olloquiソリューション、まだ結果はviewController1が押されたが、何のナビゲーションバーが表示されていない、私は唯一のバナーを持っている

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    [self.window setBackgroundColor:[UIColor redColor]]; 

    UIView *bannerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 44)]; 
    [self.window addSubview:bannerView]; 

    UIView *navigationView = [[UIView alloc] initWithFrame:CGRectMake(0, 44, 320, 416)]; 

    ViewController1 *viewController1 = [[ViewController1 alloc] initWithNibName:@"ViewController1" bundle:nil]; 
    self.navigationController = [[UINavigationController alloc] initWithRootViewController:viewController1]; 
    self.navigationController.navigationBar.frame = CGRectMake(0, 0, 320, 44); 

    [navigationView addSubview:self.navigationController.navigationBar]; 

    [self.window addSubview:navigationView]; 

    self.window.rootViewController = self.navigationController; 

    self.window.autoresizesSubviews = YES; 

    [self.window makeKeyAndVisible]; 
    return YES; 
} 

を働いていません。私は本当にこれを理解する必要があります、誰も異なるアプローチを持っていますか?

+0

なぜXIB自体にあなたの意見にバナーを入れていませんか? uiviewcontrollerはそれを他のビューとともに管理します。 – onnoweb

+0

@onnoweb、それが私が "固定"トップバナーを指定した理由です。私は、ナビゲーションがバナーに影響を与えたくないので、ユーザーが複数のView Controllerをナビゲートしている間は、バナーは静止していなければなりません。 –

+0

これがiOS 5の場合のみ、 'load view'で' [self addChildViewController:navigationController] 'を呼び出す必要があります。 –

答えて

1

このウィンドウでは、rootViewControllerプロパティによって制御されるルートビューが必要です。バックグラウンドから戻るとき、ウィンドウはrootViewControllerを要求して、そのView Controllerのビューの外観を復元します。それは、すべてのサブビューをリフレッシュするよう要求しません。

これを修正するには、新しいルートビューコントローラを作成します。これには、バナーとナビゲーションコントローラがあります。そのナビゲーションコントローラは通常のビューコントローラを保持し、ナビゲーションを管理します。バナーは、アプリがバックグラウンドから戻るときに正しく表示されます。ナビゲーションコントローラ内でナビゲーションが行われている間は、バナーが停止します。

編集:私は小さなサンプルプログラムを作成しました。

私は単純なシングルビューのアプリテンプレートから始めました。コンテンツ用の2つのビューコントローラを追加しました。差別化のためのラベルがあり、2つ目のビューをロードするボタンがあります。

すべての魔法は、メインビューコントローラのviewDidLoadメソッドで起こる:このビューの

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
// Do any additional setup after loading the view, typically from a nib. 
    OneViewController *oneVC = [[OneViewController alloc] initWithNibName:@"OneViewController" bundle:nil]; 
    self.navController = [[UINavigationController alloc]initWithRootViewController:oneVC]; 
    self.navController.view.frame = CGRectMake(0.0, 64.0, 320.0, 416.0); 
    [self.view addSubview:self.navController.view]; 
    [self addChildViewController:self.navController]; 
} 

ペン先には、バナーの画像ビューをロードします。

The example project in on Bitbucket.

+0

実際、これは私の答えで提案したものと非常によく似ていますが、rootControllerの "the proxy"を作るviewcontrollerを使っています。私がこのプロキシから好きではないのは、あなたがiOS5でcontainerControllerを使うことができない限り、ローテーション、外見などのすべてのイベントを伝播しなければならないということです。 –

+0

@MrBerna私はあなたの提案に従って、それが動作するかどうかを知らせるように努力します、ありがとうございます。 –

+0

私はXcodeにいくつかの問題を抱えていますが、その間に私はrootViewControllerコードを投稿します。これはあなたのアイデアですか? –

1

私は前にそれを試したことがないが、私はUIWindowで2つのビュー、バナー用とナビゲーション+コンテンツのために他のものを作成するためのショットを取るだろう。次に、この2番目のビューにnavigationBarビューを挿入します。これは適切なサイズになります。私はナビゲーションが完全なウィンドウを取ろうとしているかどうかはわかりませんが、各viewWillAppear上でナビゲーションコントローラのサイズを変更することは良い解決策には見えません。試してみて、結果をコメントしてください!

+0

ありがとうございますが、私はあなたが何を意味するのかよく分かりません。「次に、この2番目のビューのnavigationBarビューを挿入してください。これは適切なサイズになります」、今私はちょうどself.window.rootViewControllerによって提供されるUINavigationBarを使用していますself.navigationController.pushViewController:アニメーションメソッド。明確にしていただけますか? –

+0

私は、このサブビューにナビゲーションコントローラのビューを追加する必要があると言いたいと思います。例:[subview2 addSubview:navBar.view] –

+0

@Olloqui、今はっきりしていますが、とにかく私はMr.Bernaの提案で達成しようとしていることは、これまで成功していなくても大丈夫です。ありがとうございました。 –

0

私は本当にこの問題を解決する必要がありました。そのため、解決策を選んだのですが、hereが見つかりました。私はまだ底に追加されたUITabBarControllerの管理を解決する必要がありますが、残りは正常に動作しているようです。ヘルプと追加のヒントのためにみんなありがとう。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 

    [self.window setBackgroundColor:[UIColor redColor]]; 

    // Create a view for the banner add the banner to this view 
    UIImageView *bannerImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 45)]; 
    bannerImageView.image = [UIImage imageNamed:@"banner"]; 

    // put this banner above the nav bar 
    UIView *bannerView = [[UIView alloc] initWithFrame:CGRectMake(0, -44, 320, 44)]; 
    [bannerView addSubview:bannerImageView]; 

    //add the tabBarController as a subview of the view 
    UITabBarController *tabBarController = [[UITabBarController alloc] init]; 
    [tabBarController.view addSubview:bannerView]; 

    // Move the root view to show status bar & banner 
    tabBarController.view.frame = CGRectMake(0, 20+44, 320, 480-20-44); 

    //add the modified logo view to window 
    [self.window addSubview:tabBarController.view]; 

    ViewController1 *viewController1 = [[ViewController1 alloc] initWithNibName:@"ViewController1" bundle:nil]; 
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController1]; 

    tabBarController.viewControllers = [NSArray arrayWithObjects:navigationController, nil]; 
    //tabBarController.tabBar.hidden = YES; 

    [self.window setRootViewController:tabBarController]; 

    [self.window makeKeyAndVisible]; 
    return YES; 
} 
1

私はあなたがこのようwindow.rootViewController.viewにバナービューを追加することで、この問題を回避しようとすることができると思う:

[window.rootViewController.view addSubview:bannerView] 
関連する問題