Saya sudah membaca banyak posting tentang orang mengalami masalah dengan viewWillAppear
ketika Anda tidak membuat tampilan hirarki Anda hanya tepat. Masalah saya adalah saya tidak tahu apa artinya itu.
Jika saya membuat RootViewController
dan memanggil addSubView
pengontrol itu, saya berharap tampilan yang ditambahkan akan dihubungkan untuk viewWillAppear
acara.
Adakah yang punya contoh hierarki tampilan terprogram kompleks yang berhasil menerima viewWillAppear
peristiwa di setiap tingkat?
Status Dokumen Apple:
Peringatan: Jika tampilan milik pengontrol tampilan ditambahkan ke hierarki tampilan secara langsung, pengontrol tampilan tidak akan menerima pesan ini. Jika Anda menyisipkan atau menambahkan tampilan ke hierarki tampilan, dan memiliki pengontrol tampilan, Anda harus mengirim pengontrol tampilan terkait pesan ini secara langsung. Gagal mengirim pengontrol tampilan, pesan ini akan mencegah animasi terkait ditampilkan.
Masalahnya adalah mereka tidak menjelaskan bagaimana melakukan ini. Apa artinya "langsung"? Bagaimana Anda "secara tidak langsung" menambahkan tampilan?
Saya cukup baru mengenal Cocoa dan iPhone jadi alangkah baiknya jika ada contoh berguna dari Apple selain omong kosong Hello World dasar.
sumber
Jawaban:
Jika Anda menggunakan pengontrol navigasi dan menyetel delegasinya, maka metode tampilan {Will, Did} {Appear, Disappear} tidak akan dipanggil.
Anda perlu menggunakan metode delegasi pengontrol navigasi sebagai gantinya:
sumber
Saya mengalami masalah yang sama ini. Cukup kirim
viewWillAppear
pesan ke pengontrol tampilan Anda sebelum Anda menambahkannya sebagai subview. (Ada satu parameter BOOL yang memberi tahu pengontrol tampilan apakah sedang dianimasikan untuk muncul atau tidak.)Lihat RootViewController.m dalam contoh Metronom.
(Saya benar-benar menemukan proyek contoh Apple bagus. Ada BANYAK lebih dari HelloWorld;)
sumber
[scrollView addSubview:controller.view];
. Saya menambahkan baris[controller viewWillAppear:NO];
setelah itu dan voila! Bekerja seperti pesona.Saya akhirnya menemukan solusi untuk ini YANG BERFUNGSI!
UINavigationControllerDelegate
Saya pikir intinya adalah mengatur delegasi kontrol navigasi Anda ke viewcontroller yang ada, dan mengimplementasikannya
UINavigationControllerDelegate
dan itu dua metode. Cemerlang! Saya sangat senang akhirnya saya menemukan solusi!sumber
Saya baru saja mengalami masalah yang sama. Dalam aplikasi saya, saya memiliki 2 pengontrol navigasi dan mendorong pengontrol tampilan yang sama di masing-masing berfungsi dalam satu kasus dan bukan di kasus lain. Maksud saya ketika mendorong pengontrol tampilan yang sama persis di yang pertama
UINavigationController
,viewWillAppear
dipanggil tetapi tidak ketika didorong di pengontrol navigasi kedua.Kemudian saya menemukan posting ini UINavigationController harus memanggil metode viewWillAppear / viewWillDisappear
Dan menyadari bahwa pengontrol navigasi kedua saya telah mendefinisikan ulang
viewWillAppear
. Menyaring kode menunjukkan bahwa saya tidak meneleponSaya menambahkannya dan berhasil!
Dokumentasinya mengatakan:
sumber
Saya telah menggunakan pengontrol navigasi. Ketika saya ingin turun ke tingkat data lain atau menampilkan tampilan kustom saya, saya menggunakan yang berikut ini:
Ketika saya melakukan ini, saya mendapatkan
viewWillAppear
fungsi untuk diaktifkan. Saya kira ini memenuhi syarat sebagai "tidak langsung" karena saya sendiri tidak menyebutaddSubView
metode yang sebenarnya . Saya tidak tahu apakah ini 100% berlaku untuk aplikasi Anda karena saya tidak tahu apakah Anda menggunakan pengontrol navigasi, tetapi mungkin itu akan memberikan petunjuk.sumber
Terima kasih iOS 13.
Penghargaan akan diberikan kepada Arek Holko . Dia benar-benar menyelamatkan hariku.
sumber
Pertama, bilah tab harus berada di tingkat akar, yaitu ditambahkan ke jendela, seperti yang dinyatakan dalam dokumentasi Apple. Ini adalah kunci untuk perilaku yang benar.
Kedua, Anda dapat menggunakan
UITabBarDelegate
/UINavigationBarDelegate
untuk meneruskan pemberitahuan secara manual, tetapi saya menemukan bahwa agar seluruh hierarki panggilan tampilan berfungsi dengan benar, yang harus saya lakukan hanyalah memanggil secara manual.dan
.. hanya SEKALI sebelum mengatur pengontrol tampilan pada pengontrol masing-masing (tepat setelah alokasi). Sejak saat itu, ia dengan benar memanggil metode ini pada pengontrol tampilan anaknya.
Hirarki saya seperti ini:
Hanya memanggil metode yang disebutkan pada pengontrol tab / nav untuk pertama kalinya memastikan bahwa SEMUA kejadian diteruskan dengan benar. Itu membuat saya tidak perlu memanggil mereka secara manual dari
UINavigationBarDelegate
/UITabBarControllerDelegate
metode.Catatan samping: Anehnya, jika tidak berhasil, metode privat
.. yang dapat Anda lihat dari callstack pada implementasi yang berfungsi, biasanya memanggil
viewWill/Did..
metode tetapi tidak sampai saya melakukan hal di atas (meskipun dipanggil).Saya pikir itu SANGAT penting bahwa
UITabBarController
ada di tingkat jendela dan dokumen tampaknya mendukung ini.Harapan yang jelas (ish), senang menjawab pertanyaan selanjutnya.
sumber
Karena tidak ada jawaban yang diterima dan orang-orang (seperti saya) mendarat di sini, saya memberikan variasi saya. Meskipun saya tidak yakin itu masalah aslinya. Ketika pengontrol navigasi ditambahkan sebagai subview ke tampilan lain, Anda harus memanggil sendiri metode viewWillAppear / Dissappear dll seperti ini:
Hanya untuk melengkapi contoh. Kode ini muncul di ViewController saya tempat saya membuat dan menambahkan pengontrol navigasi ke dalam tampilan yang saya tempatkan pada tampilan.
.h terlihat seperti ini
Dalam file pena saya memiliki tampilan dan di bawah tampilan ini saya memiliki label gambar dan wadah (tampilan lain) di mana saya meletakkan pengontrol masuk Berikut ini tampilannya. Saya harus mengacak-acak beberapa hal karena ini adalah pekerjaan untuk klien.
sumber
Tampilan ditambahkan "secara langsung" dengan menelepon
[view addSubview:subview]
. Tampilan ditambahkan "secara tidak langsung" dengan metode seperti bilah tab atau bilah navigasi yang menukar sub-tampilan.Setiap kali Anda menelepon
[view addSubview:subviewController.view]
, Anda harus menelepon[subviewController viewWillAppear:NO]
(atau YA sesuai kasus Anda).Saya mengalami masalah ini ketika saya menerapkan sistem manajemen tampilan root kustom saya sendiri untuk sub-layar dalam sebuah game. Menambahkan panggilan secara manual ke viewWillAppear menyembuhkan masalah saya.
sumber
Cara yang benar untuk melakukannya adalah menggunakan api penahanan UIViewController.
sumber
viewWillAppear:
mungkin masih tidak bisa disebutSaya menggunakan kode ini untuk pengontrol tampilan push dan pop:
Dorong:
pop:
.. dan itu bekerja dengan baik untukku.
sumber
Kesalahan yang sangat umum adalah sebagai berikut. Anda memiliki satu pandangan
UIView* a
,, dan satu lagiUIView* b
,. Anda menambahkan b ke a sebagai subview. Jika Anda mencoba memanggil viewWillAppear di b, ini tidak akan pernah diaktifkan, karena ini adalah subview dari asumber
iOS 13 menggigit aplikasi saya di sini. Jika Anda memperhatikan perubahan perilaku pada iOS 13, atur saja yang berikut ini sebelum Anda mendorongnya:
Anda mungkin juga perlu menyetelnya di .storyboard di inspektur Atribut (setel Presentasi ke Layar Penuh).
Ini akan membuat aplikasi Anda berperilaku seperti pada versi iOS sebelumnya.
sumber
Saya tidak 100% yakin akan hal ini, tetapi menurut saya menambahkan tampilan ke hierarki tampilan secara langsung berarti memanggil
-addSubview:
tampilan pengontrol tampilan (misalnya,[viewController.view addSubview:anotherViewController.view]
) daripada mendorong pengontrol tampilan baru ke tumpukan pengontrol navigasi.sumber
Menurut saya, menambahkan subview tidak selalu berarti tampilan akan muncul, jadi tidak ada panggilan otomatis ke metode kelas yang akan ditampilkan.
sumber
Saya pikir apa yang mereka maksud "secara langsung" adalah dengan menghubungkan semuanya dengan cara yang sama seperti template "Aplikasi Navigasi" xcode, yang menetapkan UINavigationController sebagai satu-satunya subview dari UIWindow aplikasi.
Menggunakan template itu adalah satu-satunya cara saya bisa mendapatkan metode Will / Did / Appear / Disappear yang dipanggil pada objek ViewControllers setelah push / pops dari pengontrol tersebut di UINavigationController. Tidak ada solusi lain dalam jawaban di sini yang berfungsi untuk saya, termasuk menerapkannya di RootController dan meneruskannya ke NavigationController (anak). Fungsi-fungsi tersebut (akan / did / muncul / menghilang) hanya dipanggil di RootController saya setelah menampilkan / menyembunyikan VC level atas, "login" dan VC navigasi saya, bukan sub-VC di pengontrol navigasi, jadi saya tidak memiliki kesempatan untuk "melewati mereka" ke Nav VC.
Saya akhirnya menggunakan fungsi delegasi UINavigationController untuk mencari transisi tertentu yang memerlukan fungsionalitas tindak lanjut di aplikasi saya, dan berfungsi, tetapi memerlukan sedikit lebih banyak pekerjaan untuk mendapatkan fungsionalitas menghilang dan muncul "disimulasikan".
Juga masalah prinsip untuk membuatnya bekerja setelah membenturkan kepala saya terhadap masalah ini selama berjam-jam hari ini. Setiap cuplikan kode yang berfungsi menggunakan RootController khusus dan VC navigasi anak akan sangat dihargai.
sumber
Dalam hal ini membantu siapa pun. Saya memiliki masalah serupa di mana saya
ViewWillAppear
tidak menembaki aUITableViewController
. Setelah banyak bermain-main, saya menyadari bahwa masalahnya adalah bahwaUINavigationController
yang mengontrol sayaUITableView
tidak pada tampilan root. Setelah saya memperbaikinya, sekarang berfungsi seperti juara.sumber
Saya baru saja mengalami masalah ini sendiri dan saya butuh waktu 3 jam penuh (2 di antaranya googling) untuk memperbaikinya.
Apa yang ternyata membantu adalah cukup dengan menghapus aplikasi dari perangkat / simulator, bersihkan lalu jalankan kembali .
Semoga membantu
sumber
Setel delegasi ke pengontrol tampilan root.
sumber
Untuk Swift. Pertama buat protokol untuk memanggil apa yang ingin Anda panggil di viewWillAppear
Kedua, buat kelas
}
Ketiga, buat instance ForceUpdateOnViewAppear menjadi anggota kelas yang sesuai yang memiliki akses ke Pengontrol Navigasi dan ada selama pengontrol Navigasi ada. Ini mungkin sebagai contoh pengontrol tampilan root dari pengontrol navigasi atau kelas yang membuat atau menyajikannya. Kemudian tetapkan instance ForceUpdateOnViewAppear ke properti delegasi Pengontrol Navigasi sedini mungkin.
sumber
Dalam kasus saya, masalah dengan animasi transisi kustom. Saat disetel
modalPresentationStyle = .custom
viewWillAppear
tidak dipanggildalam kelas animasi transisi kustom perlu metode panggilan:
beginAppearanceTransition
danendAppearanceTransition
sumber
Dalam kasus saya, itu hanya bug aneh pada emulator ios 12.1. Hilang setelah diluncurkan di perangkat nyata.
sumber
Saya telah membuat kelas yang memecahkan masalah ini. Cukup setel sebagai delegasi pengontrol navigasi Anda, dan terapkan satu atau dua metode sederhana di pengontrol tampilan Anda - yang akan dipanggil saat tampilan akan ditampilkan atau telah ditampilkan melalui NavigationController
Berikut GIST yang menunjukkan kodenya
sumber
ViewWillAppear adalah metode penggantian kelas UIViewController sehingga menambahkan subView tidak akan memanggil viewWillAppear, tetapi ketika Anda mempresentasikan, push, pop, show, setFront Atau popToRootViewController dari viewController maka viewWillAppear untuk viewController yang disajikan akan dipanggil.
sumber
Masalah saya adalah bahwa viewWillAppear tidak dipanggil saat melepas dari segue. Jawabannya adalah dengan membuat panggilan ke viewWillAppear (true) dalam segmen santai di View Controller yang Anda segue kembali ke
@IBAction func unwind (untuk unwindSegue: UIStoryboardSegue, ViewController nextVC: Any) {
sumber
Saya tidak yakin ini adalah masalah yang sama yang saya selesaikan.
Dalam beberapa kesempatan, metode tidak dijalankan dengan cara biasa seperti "[self methodOne]".
Mencoba
sumber
viewWillAppear
tidak disebut sama sekaliAnda hanya boleh memiliki 1 UIViewController yang aktif setiap saat. Setiap subview yang ingin Anda manipulasi harus persis seperti itu - subVIEWS - yaitu UIView.
Saya menggunakan teknik sederhana untuk mengelola hierarki tampilan saya dan belum mengalami masalah sejak saya mulai melakukan berbagai hal dengan cara ini. Ada 2 poin utama:
Apa yang saya maksud dengan "nilai layar"? Memang sengaja dibuat agak kabur, tetapi umumnya ini adalah fitur atau bagian dari aplikasi Anda. Jika Anda memiliki beberapa layar dengan gambar latar yang sama tetapi overlay / popup berbeda, dll., Itu harus berupa 1 pengontrol tampilan dan beberapa tampilan anak. Anda seharusnya tidak pernah bekerja dengan 2 pengontrol tampilan. Perhatikan bahwa Anda masih dapat membuat instance UIView dalam satu pengontrol tampilan dan menambahkannya sebagai subview dari pengontrol tampilan lain jika Anda ingin area layar tertentu ditampilkan di beberapa pengontrol tampilan.
Adapun UINavigationController - ini adalah teman terbaik Anda! Matikan bilah navigasi dan tentukan TIDAK untuk animasi, dan Anda memiliki cara terbaik untuk beralih layar sesuai permintaan. Anda dapat mendorong dan memunculkan pengontrol tampilan jika berada dalam hierarki, atau Anda dapat menyiapkan larik pengontrol tampilan (termasuk larik yang berisi satu VC) dan menyetelnya menjadi tumpukan tampilan menggunakan setViewControllers. Ini memberi Anda kebebasan total untuk mengubah VC, sambil mendapatkan semua keuntungan bekerja dalam model yang diharapkan Apple dan membuat semua acara, dll. Diaktifkan dengan benar.
Inilah yang saya lakukan setiap kali saya memulai aplikasi:
(catatan mulai dari berbasis jendela hanyalah preferensi pribadi - Saya suka membuat sendiri jadi saya tahu persis bagaimana membuatnya. Ini akan bekerja dengan baik dengan templat berbasis tampilan)
Semua peristiwa terjadi dengan benar dan pada dasarnya hidup itu baik. Anda kemudian dapat menghabiskan seluruh waktu Anda untuk menulis bagian-bagian penting dari aplikasi Anda dan tidak mengotak-atik mencoba meretas hierarki tampilan secara manual.
sumber