iPhone: Tampilkan modal UITableViewController dengan bilah Navigasi

87

Saya menunjukkan tampilan modal yang merupakan UITableViewControllerkelas. Untuk beberapa alasan itu tidak akan menampilkan bilah navigasi ketika saya menunjukkannya. Ini kode saya:

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

Saya pikir itu ditampilkan secara default? Jika membantu, saya memanggil ini dari kelas lain yang juga UITableViewControllerdikelola oleh a UINavigationController. Ide ide?

Nic Hubbard
sumber

Jawaban:

146

Saat Anda menyajikan pengontrol tampilan modal itu tidak menggunakan pengontrol navigasi atau bilah navigasi yang ada. Jika yang Anda inginkan hanyalah menampilkan bilah navigasi, Anda perlu menambahkan bilah navigasi sebagai subview dari tampilan modal Anda dan menampilkannya saat Anda melakukannya.

Jika Anda ingin menyajikan pengontrol tampilan modal dengan fungsionalitas navigasi, Anda perlu menyajikan pengontrol navigasi modal yang berisi pengontrol tampilan detail Anda, seperti ini:

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

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

Pengontrol modal Anda akan mengelola tumpukan navigasinya sendiri.

BoltClock
sumber
Terima kasih, saya menghargai penjelasannya jadi saya tahu apa yang telah saya lakukan salah.
Nic Hubbard
1
Jika Anda menggunakan storyboard, tidak ada coding sama sekali untuk melakukannya. Solusi bagus!
Jelle
36

Berikut adalah salah satu cara untuk menampilkan bilah navigasi bagi mereka yang menggunakan papan cerita, disarankan oleh Tutorial Apple di Papan Cerita .

Karena pengontrol tampilan modal tidak ditambahkan ke tumpukan navigasi, ia tidak mendapatkan bilah navigasi dari pengontrol navigasi pengontrol tampilan tabel. Untuk memberikan bilah navigasi pada pengontrol tampilan saat disajikan secara sederhana, sematkan di pengontrol navigasinya sendiri.

  1. Dalam tampilan kerangka, pilih Lihat Kontroler.
  2. Dengan pengontrol tampilan dipilih, pilih Editor> Sematkan Di> Pengontrol Navigasi.
Scott
sumber
Pastikan Anda menambahkan segue modal ke Pengontrol Navigasi dan bukan TableViewController
bickster
Dalam situasi halaman edit profil pengguna Twitter. Ini adalah UITableViewController yang disajikan secara sederhana dan memiliki tombol DONE dan CANCEL di bagian atas. Jawaban ini tidak masuk akal secara semantik dalam situasi itu karena tidak ada navigasi yang terjadi.
William Entriken
17

Di iOS 7 dan Anda hanya ingin bilah navigasi di pengontrol tampilan modal Anda menampilkan judul dan beberapa tombol? Coba keajaiban ini di UITableViewController Anda:

// 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];
}
malhal
sumber
Seam menjadi cara yang bagus untuk melakukan sesuatu. tetapi ketika saya mencoba menggunakan Static UITableViewController, saya tidak dapat menggulir tampilan tabel lagi. tahu kenapa?
Thomas Besnehard
2
saat ini Anda akan lebih baik memasukkannya ke dalam pengontrol navigasi.
malhal
Itu solusi yang bagus tapi satu masalah kecil adalah ketika Anda menggulir judul sel yang ditampilkan di atas bilah navigasi.
Ali
Saya menyelesaikannya dengan menambahkan [self.view bringSubviewToFront:self.navigationBar];di akhir -(void)layoutNavigationBar.
Ali
7

Saya ingin berbagi bagaimana solusi yang diterima dapat digunakan dalam proyek dengan papan cerita:

Pendekatan sederhananya adalah dengan meletakkan pengontrol navigasi kosong storyboard sebelum VC yang akan disajikan secara sederhana, sehingga hubungannya terlihat seperti:

(Presenter VC) -> menyajikan secara sederhana -> (pengontrol navigasi memiliki pengontrol untuk ditampilkan sebagai root).

Kami telah mencoba pendekatan ini untuk sementara waktu dan menemukan bahwa storyboard kami menjadi "tercemar" oleh sejumlah besar pengontrol navigasi perantara saat masing-masing! dari mereka digunakan secara eksklusif untuk satu! presentasi dari beberapa pengontrol lain, yang kami ingin disajikan secara sederhana dengan bilah navigasi.

Solusi kami saat ini adalah merangkum kode dari jawaban yang diterima ke segmen khusus:

#import "ModalPresentationWithNavigationBarSegue.h"

@implementation ModalPresentationWithNavigationBarSegue

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

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

Memiliki segue ini dalam proyek kami, kami tidak membuat pengontrol navigasi perantara di storyboard kami lagi, kami hanya menggunakan ModalPresentationWithNavigationBarSegue ini seperti:

Presenter VC -> Presentee VC

Saya berharap jawaban ini akan bermanfaat bagi orang-orang yang suka menghindari duplikasi yang tidak perlu di papan cerita aplikasi mereka.

Stanislav Pankevich
sumber
5

Jika Anda hanya membutuhkan NavigationBar, Anda dapat menambahkan instance dari UINavigationBardan menetapkan BarItems ke dalamnya.

xhan
sumber
Itu tergantung pada ViewController: i think you cant menambahkan UINavigationBar ke UITableViewController, bukan?
Tobias
Di IB, buka Editor -> Sematkan di Pengontrol Navigasi, dan Anda akan memiliki Bilah Navigasi. Seret dan tambahkan BarButtonItems ke dalamnya.
AmitaiB
5

Saya hanya ingin menambahkan sesuatu pada apa yang dikatakan @Scott. Jawabannya jelas merupakan cara termudah dan paling diterima untuk melakukannya sekarang dengan Storyboards, iOS 7 dan 8 ... (dan segera, 9).

Pasti menambahkan pengontrol tampilan ke Storyboard dan Menyematkannya seperti yang dijelaskan oleh @Scott adalah cara yang tepat.

Kemudian, cukup tambahkan segue dengan menggeser kontrol dari pengontrol tampilan sumber ke target (yang ingin Anda tampilkan secara sederhana), pilih "Present Modally" saat tampilan kecil muncul dengan pilihan untuk jenis segue. Mungkin bagus untuk memberinya nama juga (dalam contoh di bawah ini saya menggunakan "presentMyModalViewController").

Satu hal yang saya butuhkan yang hilang adalah kasus @ Scott adalah ketika Anda ingin benar-benar meneruskan beberapa data ke pengontrol tampilan yang disajikan secara sederhana yang tertanam di pengontrol navigasi.

Jika Anda mengambil segue.destinationViewController, itu akan menjadi UINavigationController, bukan pengontrol yang Anda sematkan di UINavigationController.

Jadi, untuk mendapatkan pengontrol tampilan tertanam di dalam pengontrol navigasi, inilah yang saya lakukan:

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

Semoga ini membantu!

Evan K. Stone
sumber