Peringatan: -Menampilkan pengontrol tampilan pada pengontrol tampilan terpisah tidak disarankan


180

Di aplikasi saya, saya menggunakan pengontrol navigasi. Kemudian dalam beberapa tampilan saya menggunakan presentViewControlleruntuk menampilkan gambar yang diperbesar. Juga saya tidak menggunakan Storyboard atau nib.

Saya mendapatkan kesalahan ini hanya di iOS 7. Ini berfungsi dengan baik di iOS 6 dan sebelumnya:

Menyajikan pengontrol tampilan pada pengontrol tampilan terpisah tidak disarankan


Saya belum tahu. Tetapi dalam aplikasi saya, saya tidak menugaskan viewcontroller ke window.rootviewcontroller. saya menambahkan tampilan ke jendela. Mungkin itulah alasan saya. tapi tidak yakin ...
Gagan Joshi

@GaganJoshi Alasan yang Anda sebutkan di atas mungkin bukan penyebabnya. Bahkan saya menghadapi masalah yang sama. Dan dalam proyek kami, saya menugaskan view controller ke window.rootviewcontroller.
Rajesh

1
Saya pikir komentar lain dengan benar menghubungkan ini dengan sesuatu tentang rootViewController dan koneksi jendela. Saya belum cukup mengetahuinya, tetapi saya dapat mengatasi masalah ini dengan menghadirkan pengontrol langsung pada rootViewController alih-alih pada pengontrol navigasi atau salah satu dari anak-anaknya.
Rich Waters

Jawaban:


207

Untuk menghindari peringatan dalam navigasi push, Anda dapat langsung menggunakan:

[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];

Dan kemudian di pengontrol tampilan modal Anda, ketika semuanya sudah selesai, Anda bisa memanggil:

[self dismissViewControllerAnimated:YES completion:nil];


Saya menghadirkan pemetik gambar dengan kode baris ini "[self.view.window.rootViewController presentViewController: animasi viewController: YES completion: nil];" Tetapi tidak dapat mengabaikan tampilan poicker dengan baris ini "[self dismissViewControllerAnimated: YES completion: nil];" Opsi alternatif apa pun untuk dismisscontroller
kb920

@keyurbhalodiya Anda perlu memanggil metode dismissViewController dari modalView untuk membuatnya bekerja. Jadi jika Anda menampilkan tampilan bernama viewB dari viewA dengan [viewA.window.rootViewController presentViewController: viewB], di viewB Anda perlu menambahkan tombol misalnya, terkait dengan tindakan kustom yang memanggil [self dismissViewControllerAnimated]. Apakah ini lebih jelas?
cdescours

11
Tidak menghadirkan viewcontroller di iOS 8.
Rajesh Maurya

1
untuk iOS 8: [self.view.window.rootViewController.navigationController
Fede Cugliandolo

31
menggunakan self.navigationControllermelakukannya untuk saya.
Brandon Zacharie

62

Alasan peringatan ini adalah saya menghadirkan pengendali tampilan atas tampilan kecil yang bukan tampilan ukuran penuh. Diberikan di bawah ini adalah gambar proyek saya. di mana di klik pada empat opsi di atas. Navigasi pengguna ke tampilan childviewcontroller yang berbeda. (Berfungsi seperti tabViewcontroller). Tetapi childviewcontroller berisi tampilan ukuran kecil. Jadi, jika kami menyajikan pandangan dari childviewcontroller itu memberikan peringatan ini.

tampilan detail utama

Dan untuk menghindari ini, Anda bisa menyajikan pandangan tentang orangtua childviewcontroller

  [self.parentViewController presentViewController:viewController animated:YES completion:nil];

1
[self.view.window.rootViewController.navigationController pushViewController: YOUR_VIEW_CONTROLER animasi: YES];
Fede Cugliandolo

1
"Mempresentasikan view controller pada tampilan kecil yang bukan tampilan ukuran penuh." ... PERSIS. Kerja bagus.
Fattie

61

Tunggu viewDidAppear() :

Kesalahan ini juga dapat muncul jika Anda mencoba menghadirkan pengontrol tampilan sebelum tampilan benar-benar muncul, misalnya menyajikan tampilan di viewWillAppear()atau sebelumnya. Cobalah untuk menyajikan tampilan lain setelah viewDidAppear()atau di dalamnya.


9
Dengan kata lain, jangan tampilkan pengontrol tampilan di viewDidLoad(), orang! Saya telah membuat kesalahan ini berkali-kali ...
T Blank

Terima kasih, ini membantu. Saya punya kode di viewDidLoad di mana ia mencoba menampilkan dialog di akhir.
ArdenDev

Saya mendapatkan kesalahan ini ketika menjalankan tes unit / integrasi di mana saya tidak menguji dengan animasi.
mixtly87

21

Dalam kasus saya, saya memiliki sampleViewControllerpandangan yang ditambahkan sebagai subview, kemudian mencoba menyajikan popover dari tampilan sampleViewController(di sini selfsebagai UIViewControllercontoh):

[self.view addSubview:sampleViewController.view];

Cara yang benar harus di bawah ini:

// make sure the vc has been added as a child view controller as well
[self addChildViewController:sampleViewController];
[self.view addSubview:sampleViewController.view];
[sampleViewController didMoveToParentViewController:self];

Btw, ini juga berfungsi untuk case yang menampilkan popover dari sel tableview, Anda hanya perlu memastikan bahwa pengontrol tableview telah ditambahkan sebagai pengontrol tampilan anak.


Selain itu panggilan didMoveToParentViewController. Mohon lihat Tambah dan Hapus ChildViewController: gist.github.com/tomohisa/2897676
Jakehao

@ jianzong saya ingat tidak perlu melakukan langkah terakhir. Bagaimanapun, izinkan saya menambahkannya, terima kasih. :)
Kjuly

Ya itu akan berhasil tanpa langkah terakhir. Saya pikir tujuannya adalah untuk menginformasikan parentViewController sehingga akan memanggil beberapa metode untuk melakukan sesuatu. :)
Jakehao

2
ini bekerja untuk saya, saya menggunakan tampilan satu kontroler di controller lain - (Tampilan kontainer secara programatik), saya tidak menambahkan [self addChildViewController:sampleViewController];, sekarang saya menambahkan ini, terima kasih
anjnkmr

16

Saya pikir masalahnya adalah bahwa Anda tidak memiliki hierarki pengendali tampilan yang tepat. Atur rootviewcontroller aplikasi dan kemudian tampilkan tampilan baru dengan mendorong atau menghadirkan pengontrol tampilan baru pada aplikasi tersebut. Biarkan setiap pengontrol tampilan mengelola tampilan mereka. Hanya pengontrol tampilan wadah, seperti tabbarviewcontroller, yang harus menambahkan tampilan pengontrol tampilan lain ke tampilan mereka sendiri. Baca panduan pemrograman view controller untuk mempelajari lebih lanjut tentang cara menggunakan view controller dengan benar. https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/


14

Cepat 3

Bagi siapa pun yang tersandung pada ini, inilah jawaban cepatnya.

self.parent?.present(viewController, animated: true, completion: nil)

9

Saya memiliki masalah yang hampir sama. Alasannya adalah bahwa saya mencoba untuk menyajikan "beberapa" controller pada yang lain dan setelah animasi selesai saya menetapkan controller yang disajikan sebagai root. Setelah operasi ini, semua pengontrol lebih lanjut yang hadir membawa saya ke peringatan: " Menampilkan pengontrol tampilan pada pengontrol tampilan terpisah tidak disarankan ". Dan saya memecahkan peringatan ini hanya pengaturan "beberapa" controller sebagai root tanpa presentasi di awal.

Dihapus:

[[self rootController] presentViewController:controller animated:YES completion:^{

       [self window].rootViewController = controller;

       [[self window] makeKeyAndVisible];}];

Jadikan sebagai root tanpa presentasi:

 [[self window] setRootViewController:controller];

1
Ini persis masalah saya. Sedang berusaha menyajikannya dengan UIModalTransitionStyleCrossDissolve dan kemudian menjadikannya rootViewController. Setelah itu, semua presentasi lain gagal dengan pesan peringatan yang diberikan. Hanya mengaturnya sebagai rootViewcontroller tanpa animasi melakukan trik. Terima kasih!
Bernardo Oliveira

7

Salah satu solusi untuk ini adalah jika Anda memiliki childviewcontroller Jadi Anda cukup menampilkan viewviewcontroller pada induknya

[self.parentViewController presentViewController:viewController animated:YES completion:nil];

Dan untuk pemberhentian menggunakan pengontrol disissview yang sama.

[self dismissViewControllerAnimated:YES completion:nil];

Ini solusi sempurna bekerja untuk saya.


7

Gunakan [self.navigationController presentViewController:xxx animated:YES completion:nil]di iOS 8.


5

Coba kode ini

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>];

[self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];

4

Coba sajikan TabBarControllerjika ini adalah TabBarControlleraplikasi berbasis.

[self.tabBarController presentViewController:viewController animated:YES completion:nil];

Alasan mungkin selfadalah anak dari TabBarControllerdan Anda mencoba untuk menyajikan dari ChildViewController.


4

Ya, saya juga menghadapi pesan peringatan yang sama saat menampilkan pengontrol Peringatan yang berada di tampilan lain. Kemudian saya menghindari ini dengan menghadirkan pengontrol lansiran dari pengontrol tampilan induk seperti di bawah ini:

[self.parentViewController presentViewController:alertController animated:YES completion:nil];

3

Anda perlu menambahkan pengontrol tampilan yang akan menampilkan pengontrol baru sebagai anak dari pengontrol tampilan induk.

Katakanlah Anda memilikiMainViewController Anda, lalu Anda menambahkan controller baru yang disebut controllerA, dan kemudian Anda ingin menyajikan controller baru yang disebut controllerB dari controllerA

Anda harus menulis sesuatu seperti ini:

[self addChildViewController:controllerA]; //self is yourMainViewController
[self.view addsubView:controllerA.view]; 

dan di dalam controllerA Anda dapat menyajikan controller baru tanpa peringatan

[self presentViewController:controllerB animated:YES completion:nil]; //self is controllerA

3

Dalam Swift 4.1 dan Xcode 9.4.1

Solusinya adalah

DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

Jika menulis seperti ini saya mendapatkan kesalahan yang sama

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
    })
alert.addAction(defaultAction)

present(alert, animated: true, completion: nil) 

Saya mendapatkan kesalahan yang sama

Presenting view controllers on detached view controllers is discouraged <MyAppName.ViewController: 0x7fa95560Z070>.

Solusi lengkapnya adalah

let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
     })
alert.addAction(defaultAction)
//Made Changes here    
DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

Menjalankannya melalui DispatchQueue seperti ini bekerja untuk saya. Saya melakukan performSegue ke pengontrol tampilan modal, dipanggil dari viewDidLoad pada pengontrol tampilan pertama saya (layar intro peluncuran pertama untuk mengarahkan pengguna baru). Itu memuat baik-baik saja, tetapi menghasilkan peringatan. Membungkus panggilan performSegue di panggilan async DispatchQueue menghilangkan peringatan. Terima kasih!
Grant Neufeld

1

Pastikan Anda memiliki pengontrol tampilan root untuk memulai. Anda dapat mengaturnya didFinishLaunchingWithOptions.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    [window setRootViewController:viewController];
}

1

Banyak alasan untuk peringatan ini. Milik saya karena saya memiliki segue yang terhubung dari ViewController ke yang lain yang akan disajikan secara digital. Tapi, ViewController yang saya tunjukkan sedang dihasilkan secara dinamis oleh PageViewController. Karena itulah ia terlepas di Storyboard. Aplikasi saya tidak akan macet karenanya; tapi saya ingin membungkam peringatan itu.


1

Saya sampai di utas ini di mana saya memiliki Custom Navigation Bar dan saya memanggil AlertViewController melaluinya.

Saya harus menambahkannya sebagai anak ke pengendali tampilan utama saya. Lalu aku bisa memanggilnya tanpa peringatan.

Anda harus menambahkan Zoomed Image View Controller sebagai anak dari ViewController utama.

(misalnya)

[self addChildViewController:ZoomedImageViewController];

Maka Anda akan dapat memanggil ZoomedImageViewController Anda

[self presentViewController:ZoomedImageViewController];

1

Banyak jawaban yang benar.

  • Periksa presentingViewController Anda apakah memiliki parentViewController atau tidak.
  • Jika tidak, tambahkan ke tempat yang seharusnya ditambahkan
  • selain itu, periksa apakah parentViewController memiliki parentViewController secara rekursif sampai setiap viewController memiliki orangtua

Masalah ini terjadi pada saya ketika rekan kerja saya menambahkan AViewController ke BViewController. Entah bagaimana, dia hanya menambahkan tampilan AViewController ke tampilan BViewController.

Diperbaiki dengan menambahkan bViewController.addChild (aViewController)


1
Terima kasih! menambahkan addChild di blok penyelesaian Hero.share.transition saya sepenuhnya menyelesaikan masalah saya.
landnbloc

0

Itu tergantung jika Anda ingin menunjukkan peringatan Anda atau sesuatu yang serupa di mana saja dari jenis UIViewController.

Anda dapat menggunakan contoh kode ini:

UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Example" preferredStyle:UIAlertControllerStyleAlert];

UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil];

[alert addAction:cancelAction];


[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alert animated:true completion:nil];

Dengan kode Anda, itu tidak berfungsi dan memberikan log iniAttempt to present <UIAlertController: 0x7fc01a1eb600> on <ViewController: 0x7fc019821e00> whose view is not in the window hierarchy!
Naveed Abbas
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.