1

そのため、アプリケーションUIWindowに固定のトップバナーを表示し、複数のViewControllerのナビゲーションを機能させることを目指しています。これを実行する方法は他にもあることは知っていますが、プロジェクトの要件については、xibsを使用する必要があります。

以下のコードはこれを達成することを可能にします:

- (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;
}

次に、各ViewController viewWillAppearメソッドで、バナーの下に表示するために、self.viewとself.navigationController.navigationBar.frameの両方のサイズを変更しました。

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が表示されます。

アプリケーションがアクティブに戻ったときにUIWindowheaderViewが消える理由を誰もが理解していますか?

編集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;

}

編集2:2番目に考えられる解決策、まだ機能していない

- (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]];
}

これは、viewController1をプッシュしなくても問題ないように見える結果です(黄色の背景はrootViewControllerからのものであることに注意してください)。

プッシュなし

代わりに、これは次を追加した結果です。

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

PUSH付き

新しいViewControllerは押されず(背景は黒である必要があります)、ナビゲーションバーが消えています。

編集3:Olloquiソリューション、まだ機能していません

- (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;
}

結果は、バナーのみで、viewController1がプッシュされますが、ナビゲーションバーが表示されません。私は本当にこれを理解する必要があります、誰かが別のアプローチを持っていますか?

4

4 に答える 4

1

次のように window.rootViewController.view にバナー ビューを追加することで、この問題を回避できると思います。

[window.rootViewController.view addSubview:bannerView]
于 2013-12-26T07:26:26.743 に答える
1

The window expects to have a root view controlled by its rootViewController property. When returning from the background the window only asks for the rootViewController to restore the appearance of that view controller's view. It doesn't ask all subviews to refresh.

To fix this I would create a new root view controller. This would have the banner and the navigation controller. That navigation controller would then hold your normal view controllers and manage the navigation. The banner will appear properly upon the app returning from the background. Your banner will be stationary while navigation occurs within the navigation controller.

Edit: I whipped up a little example program.

I started with a simple single view app template. I added two view controllers for the content. The just have labels for differentiation, and one has a button that loads the second view.

All the magic happens in the main view controller's viewDidLoad method:

- (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 nib for this view loads the image view for the banner.

The example project in on Bitbucket.

于 2012-05-03T15:51:36.537 に答える
1

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

于 2012-05-03T15:51:47.077 に答える
0

わかりました、私は本当にこれをできるだけ早く解決する必要があったので、幸運にもここで見つけることができた解決策を選びました. 一番下に追加された 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;
}
于 2012-05-04T12:31:53.690 に答える