Saya telah mengalami beberapa kasus sekarang di mana akan lebih mudah untuk dapat menemukan controller tampilan "paling atas" (yang bertanggung jawab atas tampilan saat ini), tetapi belum menemukan cara untuk melakukannya.
Pada dasarnya tantangannya adalah ini: Mengingat bahwa seseorang mengeksekusi di kelas yang bukan pengontrol tampilan (atau tampilan) [dan tidak memiliki alamat tampilan aktif] dan belum melewati alamat pengontrol tampilan teratas ( atau, katakanlah, alamat pengontrol navigasi), apakah mungkin untuk menemukan pengontrol tampilan itu? (Dan, jika ya, bagaimana?)
Atau, jika gagal, apakah mungkin untuk menemukan tampilan teratas?
ios
objective-c
uiview
uiviewcontroller
uikit
Hot Licks
sumber
sumber
Jawaban:
iOS 4 memperkenalkan properti rootViewController di UIWindow:
Anda harus mengaturnya sendiri setelah membuat pengendali tampilan.
sumber
-[UINavigationController topViewController]
). Lalu ada kata "root", yang merupakan akar dari pohon (seperti-[UIWindow rootViewController]
.Saya pikir Anda memerlukan kombinasi dari jawaban yang diterima dan @ fishstix
Swift 3.0+
sumber
UINavigationController
dan memintatopViewController
atau bahkan memeriksaUITabBarController
dan memintaselectedViewController
. Ini akan membuat Anda pengontrol tampilan yang saat ini dapat dilihat oleh pengguna.Untuk menyelesaikan jawaban JonasG (yang meninggalkan pengontrol tab bar saat melintasi), inilah versi saya mengembalikan pengontrol tampilan yang saat ini terlihat:
sumber
childViewControllers
Versi non-rekursif lengkap, menangani berbagai skenario:
UINavigationController
UITabBarController
Objektif-C
Swift 4+
sumber
visibleViewController
untuk memperjelas apa yang dilakukannya.Mendapatkan pengontrol tampilan terbanyak untuk Swift menggunakan ekstensi
Kode:
Pemakaian:
sumber
Untuk melengkapi jawaban Eric (yang mengabaikan popovers, pengontrol navigasi, pengontrol tabbar, pengontrol tampilan ditambahkan sebagai subview ke beberapa pengontrol tampilan lainnya saat melintasi), ini adalah versi saya untuk mengembalikan pengontrol tampilan yang saat ini terlihat:
================================================== ===================
================================================== ===================
Dan sekarang yang perlu Anda lakukan untuk mendapatkan sebagian besar view controller adalah memanggil metode di atas sebagai berikut:
sumber
Jawaban ini mencakup
childViewControllers
dan memelihara implementasi yang bersih dan mudah dibaca.sumber
Saya baru-baru ini mendapatkan situasi ini dalam satu proyek saya, yang diperlukan untuk menampilkan tampilan pemberitahuan apa pun yang ditampilkan oleh pengontrol dan apa pun jenisnya (UINavigationController, pengontrol klasik atau pengontrol tampilan kustom), ketika status jaringan berubah.
Jadi saya baru saja merilis kode saya, yang cukup mudah dan sebenarnya didasarkan pada protokol sehingga fleksibel dengan setiap jenis pengontrol wadah. Tampaknya terkait dengan jawaban terakhir, tetapi dengan cara yang fleksibel.
Anda dapat mengambil kode di sini: PPTopMostController
Dan mendapat pengontrol paling atas menggunakan
sumber
Ini adalah peningkatan dari jawaban Eric:
_topMostController(UIViewController *cont)
adalah fungsi pembantu.Sekarang yang perlu Anda lakukan hanyalah menelepon
topMostController()
dan yang paling top UIViewController harus dikembalikan!sumber
self
seharusnya dimiliki.Ini pendapat saya tentang ini. Terima kasih kepada @Stakenborg karena telah menunjukkan cara untuk melewatkan mendapatkan UIAlertView sebagai pengontrol terbanyak
sumber
getSomething:
pada Objective-C. Ini memiliki arti khusus (lebih lanjut: cocoadevcentral.com/articles/000082.php ) dan Anda tidak memenuhi persyaratan ini dalam kode Anda.sumber
sumber
Untuk Versi Swift terbaru:
Buat file, beri nama
UIWindowExtension.swift
dan rekatkan cuplikan berikut:Gunakan di mana saja sebagai:
sumber
switch
alih-alih jika lain. 3. tidak yakin Anda memerlukan fungsi statis juga, saya pikir Anda bisa melakukan ini dengan mudah di tingkat contoh pertama yang Anda nyatakan. 4. Mungkin yang terbaik adalah tidak membuat terlalu banyak fungsi global tapi itu masalah selera. Anda dapat menggunakan satu baris kode untuk mencapai efek fungsi global:UIApplication.sharedApplication().delegate?.window?.visibleViewController
Ekstensi sederhana untuk
UIApplication
di Swift:CATATAN:
Itu peduli di
moreNavigationController
dalamUITabBarController
Penggunaan sederhana:
sumber
Gunakan ekstensi di bawah ini untuk mengambil yang terlihat saat ini
UIViewController
. Bekerja untuk Swift 4.0 dan yang lebih baruSwift 4.0 dan kemudian:
Cara Penggunaan?
sumber
presentedViewController
pertama, sebelumUINavigationController
danUITabBarController
kasus? Jika tidak, jika view controller ditampilkan secara modular dariUINavigationController
atauUITabBarController
, itu tidak akan dikembalikan sebagai pengendali tampilan atas, meskipun itu adalah view controller yang terlihat.Namun solusi Swift lainnya
sumber
Ekstensi Swift 4.2
Gunakan dari mana saja seperti,
atau seperti,
Sesuaikan dengan kelas apa saja seperti UINavigationController, UITabBarController
Nikmati!
sumber
Inilah yang bekerja untuk saya.
Saya menemukan bahwa kadang-kadang controller nihil pada jendela kunci, karena keyWindow adalah beberapa hal OS seperti peringatan, dll.
sumber
Memperluas jawaban @ Eric, Anda harus berhati-hati bahwa keyWindow sebenarnya adalah jendela yang Anda inginkan. Jika Anda mencoba menggunakan metode ini setelah mengetuk sesuatu dalam tampilan peringatan misalnya, keyWindow sebenarnya akan menjadi jendela peringatan, dan itu akan menyebabkan masalah bagi Anda tidak diragukan lagi. Ini terjadi pada saya di alam liar ketika menangani tautan dalam melalui peringatan dan menyebabkan SIGABRT tanpa jejak STACK. Jalang total untuk debug.
Berikut kode yang saya gunakan sekarang:
Jangan ragu untuk menggabungkan ini dengan rasa apa pun untuk mengambil pengontrol tampilan atas yang Anda sukai dari jawaban lain pada pertanyaan ini.
sumber
Solusi Swift Alternatif:
sumber
Solusi ini paling lengkap. Perlu dipertimbangkan: UINavigationController UIPageViewController UITabBarController Dan pengendali tampilan yang disajikan paling atas dari pengontrol tampilan atas
Contohnya adalah di Swift 3.
Ada 3 kelebihan
sumber
Solusi ringkas namun komprehensif dalam Swift 4.2, dengan mempertimbangkan UINavigationControllers , UITabBarControllers , pengendali yang dihadirkan dan tampilan anak :
Pemakaian:
sumber
Solusi hebat di Swift, implementasikan di AppDelegate
sumber
Saya pikir sebagian besar jawaban telah sepenuhnya diabaikan
UINavigationViewController
, jadi saya menangani use case ini dengan mengikuti implementasi.sumber
Saya tahu ini sangat terlambat dan mungkin berlebihan. Tetapi berikut ini cuplikan yang saya buat yang bekerja untuk saya:
sumber
Ini berfungsi baik untuk menemukan viewController 1 teratas dari kontrol tampilan root apa pun
sumber
Tidak yakin apakah ini akan membantu apa yang Anda coba selesaikan dengan menemukan pengontrol tampilan teratas, tapi saya mencoba menyajikan pengontrol tampilan baru, tetapi jika pengontrol tampilan root saya sudah memiliki dialog modal, itu akan diblokir, jadi saya akan berputar ke atas dari semua pengontrol tampilan modal menggunakan kode ini:
sumber
Anda dapat menemukan pengontrol tampilan paling atas dengan menggunakan
sumber
self
tidak memilikinavigationController
properti.Solusi lain bergantung pada rantai responden, yang mungkin atau mungkin tidak bekerja tergantung pada apa responden pertama adalah:
Contoh kode semu:
sumber
Cepat:
Pemakaian:
sumber