objective-c - life - navigation controller objective c
Controlador de vista actual de AppDelegate? (9)
¿Hay alguna manera de obtener el controlador de vista actual desde AppDelegate? Sé que hay rootViewController, pero eso no es lo que estoy buscando.
Solución rápida:
self.window.rootViewController.presentedViewController.
Eso debería conseguirte lo que necesitas.
A menudo necesito recuperar el controlador de vista que se muestra actualmente. Podría significar el controlador de vista en la parte superior de la pila del UINavigationController actual, el controlador de vista presentado actualmente, etc. Así que escribí esta función que lo determina la mayor parte del tiempo y que puede usar dentro de una extensión de UIViewController.
Código en Swift 3 :
func currentViewController(
_ viewController: UIViewController? =
UIApplication.shared.keyWindow?.rootViewController)
-> UIViewController? {
guard let viewController =
viewController else { return nil }
if let viewController =
viewController as? UINavigationController {
if let viewController =
viewController.visibleViewController {
return currentViewController(viewController)
} else {
return currentViewController(
viewController.topViewController)
}
} else if let viewController =
viewController as? UITabBarController {
if let viewControllers =
viewController.viewControllers,
viewControllers.count > 5,
viewController.selectedIndex >= 4 {
return currentViewController(
viewController.moreNavigationController)
} else {
return currentViewController(
viewController.selectedViewController)
}
} else if let viewController =
viewController.presentedViewController {
return viewController
} else if viewController.childViewControllers.count > 0 {
return viewController.childViewControllers[0]
} else {
return viewController
}
}
Llámalo con: currentViewController()
Esto podría ayudar
- (UIViewController *)topViewController{
return [self topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}
- (UIViewController *)topViewController:(UIViewController *)rootViewController
{
if (rootViewController.presentedViewController == nil) {
return rootViewController;
}
if ([rootViewController.presentedViewController isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
return [self topViewController:lastViewController];
}
UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
return [self topViewController:presentedViewController];
}
Versión rápida:
extension UIApplication {
class func topViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(base: nav.visibleViewController)
}
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
}
Tomado de: https://gist.github.com/snikch/3661188
Obtener el objeto appDelegate:
MyAppDelegate *tmpDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Como lo sugirió Berilio, puede usar las propiedades del controlador UINavigation para acceder a su controlador de vista actual.
Entonces el código se vería así:
id myCurrentController = tmpDelegate.myNavigationController.topViewController;
o:
NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;
Para cualquier persona que no utilice un UINavigationController
sino que su controlador de vista predeterminado es un controlador UIViewController
, puede verificar qué controlador de vista está activo (o presentado) con lo siguiente en AppDelegate
:
func application(application: UIApplication, supportedInterfaceOrientationsForWindow window: UIWindow?) -> Int {
if let rootViewController = self.window!.rootViewController {
if let presentedViewController = rootViewController.presentedViewController {
return presentedViewController.supportedInterfaceOrientations()
}
} // Else current view controller is DefaultViewController
return Int(UIInterfaceOrientationMask.Portrait.rawValue)
}
Como puede ver, estoy comprobando el controlador de vista actual para admitir diferentes orientaciones de interfaz para controladores de vista específicos. Para cualquier persona interesada en usar este método para admitir específicamente lo siguiente debe colocarse en cada controlador de vista que necesite una orientación específica.
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.All.rawValue)
}
Nota: este código fue escrito con Swift 1.2
Puede obtener el controlador de vista actual desde rootViewController buscando su controlViewControlador presentado, como este:
UIViewController *parentViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
while (parentViewController.presentedViewController != nil){
parentViewController = parentViewController.presentedViewController;
}
UIViewController *currentViewController = parentViewController;
Funciona conmigo Espero eso ayude :)
Si tiene UINavigationController en appDelegate, use su propiedad topViewController o visibleViewController
Hacer una extensión:
extension UIApplication {
class func topViewController(base: UIViewController? = UIApplication.sharedApplication().keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController {
return topViewController(nav.visibleViewController)
}
if let tab = base as? UITabBarController {
let moreNavigationController = tab.moreNavigationController
if let top = moreNavigationController.topViewController where top.view.window != nil {
return topViewController(top)
} else if let selected = tab.selectedViewController {
return topViewController(selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(presented)
}
return base
}
}
Uso:
if let rootViewController = UIApplication.topViewController() {
//do sth with root view controller
}
Si el controlador de vista raíz de su aplicación es un UINavigationController
, puede hacer esto:
((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;
Del mismo modo, si es un UITabBarController
puedes hacer esto:
((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;
Por supuesto, el casting explícito como este es sucio. Mejor sería capturar la referencia a ti mismo utilizando tipos fuertes.