La corriente UIViewController
en la pantalla debe responder a las notificaciones automáticas de los APN, configurando algunas vistas de insignia. Pero, ¿cómo podría obtener el UIViewController
método in application:didReceiveRemoteNotification
: de AppDelegate.m
?
Intenté usar self.window.rootViewController
para obtener la visualización actual UIViewController
, puede ser un UINavigationViewController
u otro tipo de controlador de vista. Y descubro que la visibleViewController
propiedad de UINavigationViewController
se puede utilizar para obtener el UIViewController
en la pantalla. Pero, ¿qué podría hacer si no es un UINavigationViewController
?
Cualquier ayuda es apreciada! El código relacionado es el siguiente.
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
}
fuente
UIView
instancia. norootViewController
es necesariamente el controlador que se muestra actualmente. Está justo en la parte superior de la jerarquía de vistas.Siempre me encantan las soluciones que involucran categorías, ya que se atornillan y se pueden reutilizar fácilmente.
Entonces creé una categoría en UIWindow. Ahora puede llamar a visibleViewController en UIWindow y esto le dará el controlador de vista visible buscando en la jerarquía del controlador. Esto funciona si está utilizando la navegación y / o el controlador de barra de pestañas. Si tiene otro tipo de controlador para sugerir, hágamelo saber y puedo agregarlo.
UIWindow + PazLabs.h (archivo de encabezado)
UIWindow + PazLabs.m (archivo de implementación)
Versión rápida
fuente
Extensión simple para la aplicación UIA en Swift (se preocupa aún más por másNavigationController dentro
UITabBarController
del iPhone) :Uso simple:
Funciona perfecto :-)
ACTUALIZACIÓN para código limpio:
fuente
También puede publicar una notificación a través de NSNotificationCenter. Esto le permite lidiar con una serie de situaciones en las que atravesar la jerarquía del controlador de vista puede ser complicado, por ejemplo, cuando se presentan modales, etc.
P.ej,
En cada uno de sus controladores de vista:
También podría usar este enfoque para los controles de instrumentos que necesitan actualizarse cuando se recibe una notificación y son utilizados por varios controladores de vista. En ese caso, maneje las llamadas de observador de agregar / quitar en los métodos init y dealloc, respectivamente.
fuente
addObserver:bar
adentroviewDidLoad
? ¿Tengo que reemplazar conself
?Código
Aquí hay un enfoque que utiliza la gran sintaxis de mayúsculas y minúsculas en Swift 3/4/5 :
La idea básica es la misma que en la respuesta de zirinisp, solo está usando una sintaxis más Swift 3+.
Uso
Probablemente quieras crear un archivo llamado
UIWindowExtension.swift
. Asegúrese de que incluya laimport UIKit
declaración, ahora copie el código de extensión anterior .En el lado de la llamada, puede usarse sin ningún controlador de vista específico :
O si sabe que su controlador de vista visible es accesible desde un controlador de vista específico :
¡Espero que ayude!
fuente
presentingViewController
y pasarlopresentingViewController.presentedViewController
como parámetro al método recursivo.UIWindow.visibleViewController(from: presentedViewController)
debería serUIWindow.visibleViewController(from: presentingViewController.presentedViewController)
?presentedViewController
yviewController
es el mismo objeto y llamará al método consigo mismo hasta que la pila se desborde (juego de palabras). Así serácase let presentingViewController where viewController?.presentedViewController != nil: return UIWindow.visibleViewController(from: presentingViewController.presentedViewController)
Descubrí que iOS 8 lo ha estropeado todo. En iOS 7 hay una nueva
UITransitionView
jerarquía en la vista cada vez que tiene una presentación modalUINavigationController
. De todos modos, aquí está mi código que encuentra obtiene el VC más alto. Las llamadasgetTopMostViewController
deberían devolver un VC al que debería poder enviarle un mensajepresentViewController:animated:completion
. Su propósito es obtener un VC que pueda usar para presentar un VC modal, por lo que lo más probable es que se detenga y regrese en clases de contenedor comoUINavigationController
y NO el VC contenido dentro de ellos. No debería ser difícil adaptar el código para hacerlo también. He probado este código en varias situaciones en iOS 6, 7 y 8. Avísame si encuentras errores.fuente
Mucho menos código que todas las demás soluciones:
Versión Objective-C:
Versión Swift 2.0: (el crédito va para Steve.B)
Funciona en cualquier lugar de su aplicación, incluso con modales.
fuente
UINavigationController
que tiene sus propios hijos.Respuesta de zirinisp en Swift:
Uso:
fuente
as!
ynavigationController.visibleViewController!
para Swift 2.0Especifique el título de cada ViewController y luego obtenga el título del ViewController actual mediante el código que se proporciona a continuación.
Luego verifíquelo por su título como este
fuente
self.title = myPhotoView
¡El mío es mejor! :)
fuente
¿Por qué no solo manejar el código de notificación push en el delegado de la aplicación? ¿Está directamente relacionado con una vista?
Puede verificar si la vista de UIViewController está actualmente visible al verificar si la
window
propiedad de la vista tiene un valor. Ver más aquí .fuente
Solo suma a la respuesta @zirinisp.
Cree un archivo, asígnele un nombre
UIWindowExtension.swift
y pegue el siguiente fragmento:Úselo en cualquier lugar como:
Gracias a @zirinisp.
fuente
Con respecto a NSNotificationCenter Post anterior (lo siento, no puedo encontrar dónde publicar un comentario debajo de él ...)
En caso de que algunos recibieran el tipo de error - [NSConcreteNotification allKeys]. Cambia esto:
a esto:
fuente
Esto funcionó para mí. Tengo muchos objetivos que tienen diferentes controladores, por lo que las respuestas anteriores no parecían funcionar.
primero quieres esto dentro de tu clase AppDelegate:
entonces, en tu función
fuente
Esta es la mejor manera posible que he probado. Si debería ayudar a alguien ...
fuente
Con esto, puede obtener fácilmente el controlador de vista superior de la publicación de esta manera
Una cosa a tener en cuenta es que si hay un UIAlertController que se muestra actualmente,
UIApplication.topMostViewController
devolverá aUIAlertController
.fuente
Versión Swift 2.0 de la respuesta de jungledev
fuente
Creé una categoría para
UIApplication
con lavisibleViewControllers
propiedad. La idea principal es bastante simple. SwizzlingviewDidAppear
yviewDidDisappear
métodos enUIViewController
. En elviewDidAppear
método viewController se agrega a la pila. En elviewDidDisappear
método viewController se elimina de la pila.NSPointerArray
se usa en lugar deNSArray
almacenarUIViewController
las referencias de los débiles . Este enfoque funciona para cualquier jerarquía viewControllers.UIApplication + VisibleViewControllers.h
UIApplication + VisibleViewControllers.m
https://gist.github.com/medvedzzz/e6287b99011f2437ac0beb5a72a897f0
Versión Swift 3
UIApplication + VisibleViewControllers.swift
https://gist.github.com/medvedzzz/ee6f4071639d987793977dba04e11399
fuente
Siempre verifique su configuración de compilación si está ejecutando su aplicación con depuración o lanzamiento.
NOTA IMPORTANTE: no puede probarlo sin ejecutar su aplicación en modo de depuración
Esta fue mi solución
fuente