Arus UIViewController
di layar perlu merespons pemberitahuan push dari APN, dengan menetapkan beberapa tampilan lencana. Tetapi bagaimana saya bisa mendapatkan UIViewController
metode in application:didReceiveRemoteNotification
: of AppDelegate.m
?
Saya mencoba menggunakan self.window.rootViewController
untuk mendapatkan tampilan saat ini UIViewController
, mungkin berupa UINavigationViewController
atau beberapa jenis pengontrol tampilan lainnya. Dan saya mengetahui bahwa visibleViewController
properti dari UINavigationViewController
dapat digunakan untuk mendapatkan UIViewController
di layar. Tapi apa yang bisa saya lakukan jika itu bukan UINavigationViewController
?
Bantuan apa pun dihargai! Kode terkait adalah sebagai berikut.
AppDelegate.m
...
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//I would like to find out which view controller is on the screen here.
UIViewController *vc = [(UINavigationViewController *)self.window.rootViewController visibleViewController];
[vc performSelector:@selector(handleThePushNotification:) withObject:userInfo];
}
...
ViewControllerA.m
- (void)handleThePushNotification:(NSDictionary *)userInfo{
//set some badge view here
}
sumber
UIView
instance.rootViewController
adalah tidak tentu controller saat ditampilkan. Itu hanya di bagian atas hierarki tampilan.Saya selalu suka solusi yang melibatkan kategori karena mereka baut dan dapat dengan mudah digunakan kembali.
Jadi saya membuat kategori di UIWindow. Anda sekarang dapat memanggil visibleViewController di UIWindow dan ini akan memberi Anda pengontrol tampilan yang terlihat dengan menelusuri hierarki pengontrol. Ini berfungsi jika Anda menggunakan navigasi dan / atau pengontrol tab bar. Jika Anda memiliki tipe pengontrol lain yang disarankan, beri tahu saya dan saya dapat menambahkannya.
UIWindow + PazLabs.h (file header)
UIWindow + PazLabs.m (file implementasi)
Versi Swift
sumber
Ekstensi sederhana untuk aplikasi UIA
UITabBarController
di Swift (peduli bahkan lebih banyak tentang Navigasi Navigasi di dalam iPhone) :Penggunaan sederhana:
Bekerja sempurna :-)
UPDATE untuk kode bersih:
sumber
Anda juga dapat memposting pemberitahuan melalui NSNotificationCenter. Ini membuat Anda berurusan dengan sejumlah situasi di mana melintasi hierarki pengontrol tampilan mungkin rumit - misalnya ketika modem disajikan, dll.
Misalnya,
Di setiap Pengontrol Tampilan Anda:
Anda juga dapat menggunakan pendekatan ini untuk kontrol instrumen yang perlu diperbarui ketika pemberitahuan diterima dan digunakan oleh beberapa pengontrol tampilan. Dalam hal ini, masing-masing menangani panggilan add / remove observer di init dan dealloc.
sumber
addObserver:bar
di dalamviewDidLoad
? Apakah saya harus mengganti denganself
?Kode
Berikut ini pendekatan menggunakan sintaks kasus sakelar hebat di Swift 3/4/5 :
Ide dasarnya sama dengan jawaban zirinisp, hanya menggunakan sintaksis Swift 3+ yang lebih.
Pemakaian
Anda mungkin ingin membuat file dengan nama
UIWindowExtension.swift
. Pastikan itu termasukimport UIKit
pernyataan, sekarang salin kode ekstensi di atas .Di sisi panggilan dapat digunakan tanpa pengontrol tampilan tertentu :
Atau jika Anda tahu pengontrol tampilan Anda dapat dijangkau dari pengontrol tampilan tertentu :
Saya harap ini membantu!
sumber
presentingViewController
dan meneruskanpresentingViewController.presentedViewController
sebagai parameter ke metode rekursif.UIWindow.visibleViewController(from: presentedViewController)
mestinya sebaliknyaUIWindow.visibleViewController(from: presentingViewController.presentedViewController)
?presentedViewController
danviewController
merupakan objek yang sama dan itu akan memanggil metode itu sendiri sampai stack meluap (pun intended). Jadi itu akan terjadicase let presentingViewController where viewController?.presentedViewController != nil: return UIWindow.visibleViewController(from: presentingViewController.presentedViewController)
Saya telah menemukan bahwa iOS 8 telah mengacaukan semuanya. Di iOS 7 ada yang baru
UITransitionView
hirarki tampilan yang baru setiap kali Anda disajikan secara moderatUINavigationController
. Bagaimanapun, ini kode saya yang menemukan mendapat VC paling atas. PanggilangetTopMostViewController
harus mengembalikan VC yang seharusnya dapat Anda kirimi pesanpresentViewController:animated:completion
. Tujuannya adalah untuk memberi Anda VC yang dapat Anda gunakan untuk menyajikan modal VC, sehingga kemungkinan besar akan berhenti dan kembali di kelas wadah sepertiUINavigationController
dan BUKAN VC yang terkandung di dalamnya. Seharusnya tidak sulit untuk mengadaptasi kode untuk melakukannya juga. Saya telah menguji kode ini dalam berbagai situasi di iOS 6, 7 dan 8. Tolong beri tahu saya jika Anda menemukan bug.sumber
Kode jauh lebih sedikit daripada semua solusi lain:
Versi objektif-C:
Versi Swift 2.0: (kredit diberikan ke Steve.B)
Bekerja di mana saja di aplikasi Anda, bahkan dengan modals.
sumber
UINavigationController
yang memiliki anak sendiri.Jawaban zirinisp di Swift:
Pemakaian:
sumber
as!
dannavigationController.visibleViewController!
untuk Swift 2.0Tentukan judul untuk setiap ViewController dan kemudian dapatkan judul ViewController saat ini dengan kode yang diberikan di bawah ini.
Kemudian periksa dengan judul Anda seperti ini
sumber
self.title = myPhotoView
Punyaku lebih baik! :)
sumber
Mengapa tidak menangani kode pemberitahuan push saja di delegasi aplikasi? Apakah ini terkait langsung dengan tampilan?
Anda dapat memeriksa apakah tampilan UIViewController saat ini terlihat dengan memeriksa apakah
window
properti view-nya memiliki nilai. Lihat lebih lanjut di sini .sumber
Cukup tambahkan jawaban @zirinisp.
Buat file, beri nama
UIWindowExtension.swift
dan rekatkan cuplikan berikut:Gunakan di mana saja sebagai:
Terima kasih kepada @zirinisp.
sumber
Mengenai Posting NSNotificationCenter di atas (maaf tidak dapat mengetahui di mana memposting komentar di bawahnya ...)
Dalam kasus beberapa mendapatkan - [NSConcreteNotification allKeys] semacam kesalahan. Ubah ini:
untuk ini:
sumber
Ini berhasil untuk saya. Saya memiliki banyak target yang memiliki pengontrol yang berbeda sehingga jawaban sebelumnya sepertinya tidak berfungsi.
pertama Anda ingin ini di dalam kelas AppDelegate Anda:
kemudian, dalam fungsi Anda
sumber
Ini adalah cara terbaik yang pernah saya coba. Jika itu harus membantu siapa pun ...
sumber
Dengan ini, Anda dapat dengan mudah mendapatkan pengontrol tampilan pos atas seperti itu
Satu hal yang perlu diperhatikan adalah jika ada UIAlertController yang sedang ditampilkan,
UIApplication.topMostViewController
akan mengembalikan aUIAlertController
.sumber
Jawaban cepat versi jungledev
sumber
Saya membuat kategori untuk
UIApplication
denganvisibleViewControllers
properti. Gagasan utamanya cukup sederhana. Aku bimbangviewDidAppear
danviewDidDisappear
metode dalamUIViewController
. DalamviewDidAppear
metode viewController ditambahkan ke stack. DalamviewDidDisappear
metode viewController dihapus dari tumpukan.NSPointerArray
digunakan bukanNSArray
untuk menyimpan yang lemahUIViewController
referensi . Pendekatan ini berfungsi untuk semua hierarki viewControllers.Aplikasi UIA + VisibleViewControllers.h
Aplikasi UIA + VisibleViewControllers.m
https://gist.github.com/medvedzzz/e6287b99011f2437ac0beb5a72a897f0
Versi Swift 3
Aplikasi UIA + VisibleViewControllers.swift
https://gist.github.com/medvedzzz/ee6f4071639d987793977dba04e11399
sumber
Selalu periksa konfigurasi build Anda jika Anda menjalankan aplikasi dengan debug atau rilis.
CATATAN PENTING: Anda tidak dapat mengujinya tanpa menjalankan aplikasi dalam mode debug
Ini solusi saya
sumber