iPhone:ナビゲーションバーでモーダルUITableViewControllerを表示する


87

UITableViewControllerクラスであるモーダルビューを表示しています。何らかの理由で、ナビゲーションバーを表示しても表示されません。これが私のコードです:

SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped];
    detailViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    detailViewController.navigationController.navigationBarHidden = NO;
    [self.navigationController presentModalViewController:detailViewController animated:YES];
    detailViewController = nil;
    [detailViewController release];

デフォルトで表示されると思いましたか?それが役立つ場合は、これもUITableViewControllerによって管理されている別のクラスから呼び出しUINavigationControllerます。アイデア?

回答:


146

モーダルビューコントローラーを表示する場合、既存のナビゲーションコントローラーやナビゲーションバーは使用されません。ナビゲーションバーを表示するだけの場合は、ナビゲーションバーをモーダルビューのサブビューとして追加し、それを現在の状態で表示する必要があります。

ナビゲーション機能を備えたモーダルビューコントローラーを表示する場合は、次のように、代わりに詳細ビューコントローラーを含むモーダルナビゲーションコントローラーを表示する必要があります。

SettingsCreateAccount *detailViewController = [[SettingsCreateAccount alloc] initWithStyle:UITableViewStyleGrouped];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
[detailViewController release];

navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:navController animated:YES];
[navController release];

モーダルコントローラーは、独自のナビゲーションスタックを管理します。


ありがとう、私は説明に感謝しているので、私が間違ったことを知っています。
ニックハバード、2011年

1
ストーリーボードを使用する場合、これを実現するためのコーディングは一切必要ありません。良い解決策!
Jelle

36

AppleのStoryboard on Storyboardで提案されている、ストーリーボードを使用しているユーザー向けのナビゲーションバーを表示する方法の1つを次に示します。

モーダルビューコントローラーはナビゲーションスタックに追加されないため、テーブルビューコントローラーのナビゲーションコントローラーからナビゲーションバーを取得しません。モーダルで表示されたときにビューコントローラーにナビゲーションバーを表示するには、それを独自のナビゲーションコントローラーに埋め込みます。

  1. アウトラインビューで、View Controllerを選択します。
  2. ビューコントローラーを選択した状態で、エディター>埋め込み>ナビゲーションコントローラーを選択します。

必ずモーダルセグエをTableViewControllerではなくNavigation Controllerに追加してください
bickster

Twitterのユーザープロフィール編集ページの状況。これはモーダルに表示されるUITableViewControllerであり、上部に[完了]ボタンと[キャンセル]ボタンがあります。ナビゲーションが行われないため、この状況ではこの答えは意味的に意味をなさない。
ウィリアムEntriken 2016年

17

iOS 7で、モーダルビューコントローラーのナビゲーションバーにタイトルといくつかのボタンを表示したいだけですか?あなたのUITableViewControllerでこの魔法を試してください:

// in the .h
@property (strong) UINavigationBar* navigationBar;

//in the .m
- (void)viewDidLoad {
    [super viewDidLoad];

    self.navigationItem.title = @"Awesome";
    self.navigationBar = [[UINavigationBar alloc] initWithFrame:CGRectZero];
    [self.view addSubview:_navigationBar];
    [self.navigationBar pushNavigationItem:self.navigationItem animated:NO];
}

-(void)layoutNavigationBar{
    self.navigationBar.frame = CGRectMake(0, self.tableView.contentOffset.y, self.tableView.frame.size.width, self.topLayoutGuide.length + 44);
    self.tableView.contentInset = UIEdgeInsetsMake(self.navigationBar.frame.size.height, 0, 0, 0);
}

-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
    //no need to call super
    [self layoutNavigationBar];
}

-(void)viewDidLayoutSubviews{
    [super viewDidLayoutSubviews];
    [self layoutNavigationBar];
}

縫い目は、物事を行うための素晴らしい方法です。しかし、静的UITableViewControllerでトライすると、テーブルビューをスクロールできなくなります。なぜですか?
Thomas Besnehard、2014

2
今日では、それをナビゲーションコントローラーに埋め込むほうがよいでしょう。
マルハル

これは良い解決策ですが、小さな問題の1つは、セルヘッダーをスクロールすると、ナビゲーションバーの上にタイトルが表示されることです。
アリ

[self.view bringSubviewToFront:self.navigationBar];の最後に追加して解決しました-(void)layoutNavigationBar
アリ

7

ストーリーボードを使用したプロジェクトで、承認されたソリューションをどのように使用できるかを共有したいと思います。

シンプルなアプローチは、モーダルで表示されるVCの前にストーリーボードの空白のナビゲーションコントローラーを配置することです。そのため、関係は次のようになります。

(Presenter VC)->モーダルで表示->(ルートとして表示されるコントローラーを持つナビゲーションコントローラー)

私たちはしばらくの間このアプローチを試しましたが、ストーリーボードがそのような多数の中間ナビゲーションコントローラによってそれぞれ汚染されることに気づきました。そのうちの1つが専用に使用されます!ナビゲーションバーでモーダルに表示される他のコントローラーのプレゼンテーション。

現在の解決策は、受け入れられた回答からカスタムセグエへのコードをカプセル化することです。

#import "ModalPresentationWithNavigationBarSegue.h"

@implementation ModalPresentationWithNavigationBarSegue

- (void)perform {
    UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:self.destinationViewController];

    [self.sourceViewController presentViewController:navigationController animated:YES completion:nil];
}
@end

プロジェクトでこのセグエを使用すると、ストーリーボードに中間ナビゲーションコントローラーを作成しなくなります。このModalPresentationWithNavigationBarSegueを次のように使用するだけです。

発表者VC->発表者VC

この答えが、アプリのストーリーボードでの不必要な重複を避けたい人に役立つことを願っています。


5

だけが必要なNavigationBar場合は、のインスタンスを追加して、UINavigationBarそれにBarItemsを割り当てることができます。


それはViewControllerに依存します。UITableViewControllerにUINavigationBarを追加できないと思いますか?
トビアス

IBで、[エディター]-> [ナビゲーションコントローラーに埋め込む]に移動すると、ナビゲーションバーが表示されます。これにBarButtonItemsをドラッグして追加します。
AmitaiB 2016

5

@Scottの発言に何かを加えたかっただけです。彼の答えは間違いなく、Storyboards、iOS 7および8(そしてすぐに9)でこれを行う最も簡単で最も受け入れられた方法です。

ストーリーボードにビューコントローラを確実に追加し、@ Scottで説明されているように埋め込むのが正しい方法です。

次に、ソースビューコントローラーからターゲット(モーダルで表示するもの)にコントロールをドラッグしてセグエを追加し、セグエの種類の選択肢が表示された小さなビューが表示されたら、「現在のモーダル」を選択します。おそらく名前も付けておくとよいでしょう(以下の例では「presentMyModalViewController」を使用しています)。

欠けていた必要のある1つは、@ Scottの場合で、ナビゲーションコントローラーに埋め込まれている、モーダル表示されたビューコントローラーに実際にデータを渡したい場合です。

segue.destinationViewControllerを取得すると、UINavigationControllerに埋め込まれたコントローラーではなく、UINavigationControllerになります。

だから、ナビゲーションコントローラー内の埋め込まれたビューコントローラーを取得するには、次のようにします。

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"presentMyModalViewController"]) {
        // This could be collapsed, but it's a little easier to see
        // what's going on written out this way.

        // First get the destination view controller, which will be a UINavigationController
        UINavigationController *nvc = (UINavigationController *)segue.destinationViewController;

        // To get the view controller we're interested in, grab the navigation controller's "topViewController" property
        MyModalViewController *vc = (EmailReceiptViewController *)[nvc topViewController];

        // Now that we have the reference to our view controller, we can set its properties here:
        vc.myAwesomeProperty = @"awesome!";
    }
}

お役に立てれば!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.