Baru mulai menggunakan Xcode 4.5 dan saya mendapatkan kesalahan ini di konsol:
Peringatan: Berusaha menampilkan <finishViewController: 0x1e56e0a0> di <ViewController: 0x1ec3e000> yang pandangannya tidak ada dalam hierarki jendela!
Tampilannya masih disajikan dan semua yang ada di aplikasi berfungsi dengan baik. Apakah ini sesuatu yang baru di iOS 6?
Ini adalah kode yang saya gunakan untuk mengubah antar tampilan:
UIStoryboard *storyboard = self.storyboard;
finishViewController *finished =
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];
[self presentViewController:finished animated:NO completion:NULL];
presentViewController:animated:completion
pengontrol nav. Apakah Anda melakukan ini di delegasi aplikasi?Jawaban:
Dari mana Anda memanggil metode ini? Saya punya masalah di mana saya mencoba untuk menyajikan pengontrol tampilan modal dalam
viewDidLoad
metode. Solusi bagi saya adalah memindahkan panggilan ini keviewDidAppear:
metode.Asumsi saya adalah bahwa pandangan pengontrol tampilan tidak dalam hierarki tampilan jendela pada titik yang telah dimuat (ketika
viewDidLoad
pesan dikirim), tetapi berada dalam hierarki jendela setelah disajikan (ketikaviewDidAppear:
pesan dikirim) .Peringatan
Jika Anda melakukan panggilan ke
presentViewController:animated:completion:
dalamviewDidAppear:
Anda dapat mengalami masalah di mana pengontrol tampilan modal selalu disajikan setiap kali tampilan pengontrol tampilan muncul (yang masuk akal!) Dan pengontrol tampilan modal yang disajikan tidak akan pernah hilang. .Mungkin ini bukan tempat terbaik untuk menyajikan pengontrol tampilan modal, atau mungkin beberapa kondisi tambahan perlu dijaga yang memungkinkan pengontrol tampilan tampilan untuk memutuskan apakah harus menghadirkan pengontrol tampilan modal atau tidak.
sumber
Penyebab potensial lainnya:
Saya mengalami masalah ini ketika saya tidak sengaja menampilkan pengontrol tampilan yang sama dua kali. (Sekali dengan
performSegueWithIdentifer:sender:
yang dipanggil ketika tombol ditekan, dan yang kedua dengan segue terhubung langsung ke tombol).Secara efektif, dua segue diaktifkan pada saat yang sama, dan saya mendapatkan kesalahan:
Attempt to present X on Y whose view is not in the window hierarchy!
sumber
present(viewController, animated: true, completion: nil)
dalam satu lingkaran.viewWillLayoutSubviews
danviewDidLayoutSubviews
(iOS 5.0+) dapat digunakan untuk tujuan ini. Mereka dipanggil lebih awal dari viewDidAppear.sumber
Untuk Menampilkan subview apa pun ke tampilan utama, Silakan gunakan kode berikut
Untuk Abaikan subview apa pun dari tampilan utama, Silakan gunakan kode berikut
sumber
Saya juga mengalami masalah ini ketika saya mencoba untuk menyajikan
UIViewController
dalamviewDidLoad
. Jawaban James Bedford berhasil, tetapi aplikasi saya menunjukkan latar belakang pertama selama 1 atau 2 detik.Setelah beberapa penelitian, saya telah menemukan cara untuk menyelesaikan ini dengan menggunakan
addChildViewController
.sumber
Mungkin, seperti saya, Anda salah paham
viewController
Saya ingin menampilkan
ViewController
dalamnon-UIViewController
konteks,Jadi saya tidak bisa menggunakan kode seperti itu:
Jadi, saya mendapatkan UIViewController:
Untuk beberapa alasan (bug logis), itu
rootViewController
adalah sesuatu yang tidak diharapkan (normalUIViewController
). Lalu saya memperbaiki bug, menggantirootViewController
denganUINavigationController
, dan masalahnya hilang.sumber
TL; DR Anda hanya dapat memiliki 1 rootViewController dan yang terbaru disajikan. Jadi jangan coba-coba membuat viewcontroller menyajikan viewcontroller lain ketika sudah disajikan yang belum diberhentikan.
Setelah melakukan beberapa pengujian saya sendiri saya sampai pada kesimpulan.
Jika Anda memiliki rootViewController yang ingin Anda sajikan semuanya maka Anda dapat mengalami masalah ini.
Berikut ini adalah kode rootController saya (terbuka adalah jalan pintas saya untuk menghadirkan viewcontroller dari root).
Jika saya memanggil terbuka dua kali berturut-turut (terlepas dari waktu yang berlalu), ini akan berfungsi dengan baik pada pembukaan pertama, tetapi BUKAN pada pembukaan kedua. Upaya terbuka kedua akan menghasilkan kesalahan di atas.
Namun jika saya menutup tampilan yang paling baru disajikan kemudian memanggil terbuka, itu berfungsi dengan baik ketika saya memanggil terbuka lagi (pada viewcontroller lain).
Apa yang saya simpulkan adalah bahwa rootViewController hanya MOST-RECENT-CALL ada pada tampilan Hierarchy (bahkan jika Anda tidak mengabaikannya atau menghapus tampilan). Saya mencoba bermain dengan semua panggilan loader (viewDidLoad, viewDidAppear, dan melakukan panggilan pengiriman tertunda) dan saya telah menemukan bahwa satu-satunya cara saya bisa membuatnya bekerja adalah HANYA memanggil hadir dari pengendali tampilan paling atas.
sumber
wait
wait
decide
push screen to front
dan itu TIDAK MUNGKIN adalah IOS ????Masalah saya adalah saya tampil Shalawat di
UIApplicationDelegate
'sdidFinishLaunchingWithOptions
metode sebelum aku meneleponmakeKeyAndVisible()
di jendela.sumber
Dalam situasi saya, saya tidak dapat menempatkan kelas saya di kelas. Jadi, inilah yang saya dapat:
sumber
Saya memiliki masalah yang sama. Saya harus menanamkan pengontrol navigasi dan menyajikan pengontrol melaluinya. Di bawah ini adalah kode sampel.
sumber
Jika Anda memiliki objek AVPlayer dengan video yang diputar, Anda harus menjeda video terlebih dahulu.
sumber
Saya memiliki masalah yang sama. Masalahnya adalah, performSegueWithIdentifier dipicu oleh pemberitahuan, segera setelah saya meletakkan pemberitahuan di utas utama pesan peringatan itu hilang.
sumber
Ini bekerja dengan baik, coba ini. Tautan
sumber
Jika itu membantu siapa pun, masalah saya sangat konyol. Tentu saja ini salahku. Pemberitahuan memicu metode yang memanggil modal. Tetapi saya tidak menghapus notifikasi dengan benar, jadi pada beberapa titik, saya akan memiliki lebih dari satu notifikasi, sehingga modalnya akan dipanggil beberapa kali. Tentu saja, setelah Anda memanggil modal sekali, viewcontroller yang menyebutnya tidak lagi dalam hierarki tampilan, itu sebabnya kami melihat masalah ini. Situasi saya menyebabkan banyak masalah lain juga, seperti yang Anda harapkan.
Jadi untuk meringkas, apa pun yang Anda lakukan pastikan modal tidak dipanggil lebih dari sekali .
sumber
Saya telah berakhir dengan kode yang akhirnya bekerja untuk saya (Swift), mengingat Anda ingin menampilkan beberapa
viewController
dari hampir di mana saja. Kode ini jelas akan macet ketika tidak ada rootViewController yang tersedia, itulah akhir yang terbuka. Ini juga tidak termasuk biasanya diperlukan beralih ke menggunakan UI threadsumber
Semacam ini peringatan bisa berarti bahwa Anda sedang berusaha untuk baru hadir
View Controller
melaluiNavigation Controller
sementara iniNavigation Controller
saat menyajikan lainView Controller
. Untuk memperbaikinya Anda harus mengabaikan saat ini disajikanView Controller
pada awalnya dan pada saat selesai menyajikan yang baru. Penyebab lain dari peringatan tersebut adalah mencoba menampilkanView Controller
di utas selainmain
.sumber
Saya memiliki masalah serupa pada Swift 4.2 tetapi pandangan saya tidak disajikan dari siklus tampilan. Saya menemukan bahwa saya memiliki beberapa segmen untuk disajikan pada waktu yang bersamaan. Jadi saya menggunakan dispatchAsyncAfter.
sumber
Saya memperbaikinya dengan memindahkan
start()
fungsi di dalamdismiss
blok penyelesaian:Mulai berisi dua panggilan ke
self.present()
satu untuk UINavigationController dan satu lagi untuk aUIImagePickerController
.Itu memperbaikinya bagi saya.
sumber
Anda juga bisa mendapatkan peringatan ini saat melakukan segue dari view controller yang tertanam dalam sebuah wadah. Solusi yang benar adalah dengan menggunakan segue dari induk wadah, bukan dari pengontrol tampilan wadah.
sumber
Harus menulis di bawah garis.
dari pada
dalam UIViewController
sumber
Dengan Swift 3 ...
Kemungkinan penyebab lain untuk ini, yang terjadi pada saya, adalah memiliki segue dari tableViewCell ke ViewController lain di Storyboard. Saya juga menggunakan
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {}
ketika sel diklik.Saya memperbaiki masalah ini dengan membuat segue dari ViewController ke ViewController.
sumber
Saya mengalami masalah ini, dan akar penyebabnya berlangganan penangan klik tombol (TouchUpInside) beberapa kali.
Itu berlangganan di ViewWillAppear, yang dipanggil beberapa kali karena kami telah menambahkan navigasi untuk pergi ke pengontrol lain, dan kemudian bersantai kembali ke sana.
sumber
Itu terjadi pada saya bahwa segue di storyboard semacam rusak . Menghapus segue (dan membuat segue yang sama persis lagi) menyelesaikan masalah.
sumber
Dengan jendela utama Anda, kemungkinan akan selalu ada saat-saat dengan transisi yang tidak sesuai dengan menghadirkan peringatan. Untuk mengizinkan pemberitahuan saat kapan saja dalam siklus hidup aplikasi Anda, Anda harus memiliki jendela terpisah untuk melakukan pekerjaan itu.
Penggunaan dasar yang, menurut desain, akan selalu berhasil:
sumber
Sayangnya, solusi yang diterima tidak bekerja untuk kasus saya. Saya mencoba menavigasi ke Pengontrol Tampilan baru setelah melepas dari Pengontrol Tampilan lainnya.
Saya menemukan solusi dengan menggunakan bendera untuk menunjukkan yang mana segue santai dipanggil.
Kemudian berikan VC yang diinginkan dengan
present(_ viewControllerToPresent: UIViewController)
Pada dasarnya, kode di atas akan membuat saya menangkap pelepasan dari login / Mendaftar VC dan menavigasi ke dasbor, atau menangkap tindakan pelepasan dari lupa kata sandi VC dan menavigasi ke halaman login.
sumber
Saya memperbaiki kesalahan ini dengan menyimpan viewcontroller paling atas ke dalam konstanta yang ditemukan di dalam sementara siklus di rootViewController:
sumber
Saya menemukan bug ini tiba setelah memperbarui Xcode, saya percaya ke Swift 5 . Masalahnya terjadi ketika saya secara sistematis meluncurkan segue langsung setelah membuka gulungan pengontrol tampilan.
Solusinya tiba saat memperbaiki bug terkait, yaitu bahwa pengguna sekarang dapat melepas segues dengan menggesekkan halaman. Ini mematahkan logika program saya.
Itu diperbaiki dengan mengubah mode Presentasi pada semua pengontrol tampilan dari Otomatis ke Layar Penuh .
Anda bisa melakukannya di panel atribut di pembuat antarmuka. Atau lihat jawaban ini untuk cara melakukannya secara terprogram.
sumber
Saya hanya punya masalah ini juga, tetapi tidak ada hubungannya dengan waktu. Saya menggunakan singleton untuk menangani adegan, dan saya menetapkannya sebagai presenter. Dengan kata lain "Diri" tidak terhubung dengan apa pun. Saya baru saja membuat "adegan" batinnya sebagai presenter dan voila baru, itu berhasil. (Voila kehilangan sentuhannya setelah Anda mempelajari artinya, heh).
Jadi ya, ini bukan tentang "secara ajaib menemukan jalan yang benar", ini tentang memahami di mana kode Anda berdiri dan apa yang dilakukannya. Saya senang Apple memberikan pesan peringatan sederhana-bahasa Inggris, bahkan dengan emosi untuk itu. Kudos kepada dev apel yang melakukan itu !!
sumber
Jika solusi lain tidak terlihat bagus untuk beberapa alasan, Anda masih dapat menggunakan
workaround
presentasi tua dengan penundaan 0 ini, seperti ini:Meskipun saya telah melihat tidak ada jaminan yang terdokumentasi bahwa VC Anda akan berada pada hierarki tampilan pada blok pengiriman dijadwalkan untuk dieksekusi, saya telah mengamati itu akan berfungsi dengan baik.
Menggunakan penundaan misalnya 0,2 detik juga merupakan pilihan. Dan hal terbaik - dengan cara ini Anda tidak perlu dipusingkan dengan variabel boolean
viewDidAppear:
sumber
Ini berfungsi untuk menampilkan pengontrol tampilan, jika Anda memiliki pengontrol navigasi. self.navigationController? .present (MyViewController, animated: true, completion: nil) Juga, saya dapat menampilkan peringatan dan pengontrol email juga.
sumber