Gibt es eine Möglichkeit, den aktuellen View-Controller von AppDelegate abzurufen? Ich weiß, dass es rootViewController gibt, aber das ist nicht was ich suche.
Wenn Sie UINavigationController in appDelegate verwenden, verwenden Sie seine Eigenschaft topViewController oder visibleViewController
Wenn der Root-View-Controller Ihrer App UINavigationController
ist, können Sie Folgendes tun:
((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;
Wenn es sich um eine UITabBarController
handelt, können Sie Folgendes tun:
((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;
Das explizite Casting ist natürlich schmutzig. Besser wäre es, die Referenz selbst mit starken Typen zu erfassen.
Das könnte helfen
- (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];
}
Schnelle Version:
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
}
}
Entnommen aus: https://Gist.github.com/snikch/3661188
Machen Sie eine Erweiterung:
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
}
}
Verwendungszweck:
if let rootViewController = UIApplication.topViewController() {
//do sth with root view controller
}
Holen Sie sich das appDelegate-Objekt:
MyAppDelegate *tmpDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Wie von Beryllium vorgeschlagen, können Sie die Eigenschaften des UINavigationController für den Zugriff auf Ihren aktuellen View-Controller verwenden.
Der Code würde also so aussehen:
id myCurrentController = tmpDelegate.myNavigationController.topViewController;
oder:
NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;
Sie können den aktuellen View-Controller von rootViewController abrufen, indem Sie wie folgt nach dem präsentiertenViewController suchen:
UIViewController *parentViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
while (parentViewController.presentedViewController != nil){
parentViewController = parentViewController.presentedViewController;
}
UIViewController *currentViewController = parentViewController;
Es funktioniert bei mir. Ich hoffe es hilft :)
Schnelle Lösung:
self.window.rootViewController.presentedViewController.
Das sollte dir das geben, was du brauchst.
Für alle not, die UINavigationController
verwenden, aber der standardmäßige View-Controller ist ein UIViewController
. In AppDelegate
können Sie überprüfen, welcher View-Controller aktiv ist (oder dargestellt wird).
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)
}
Wie Sie sehen, überprüfe ich den aktuellen View-Controller, um unterschiedliche Schnittstellenausrichtungen für bestimmte View-Controller zu unterstützen. Für alle anderen, die an dieser Methode zur Unterstützung bestimmter Methoden interessiert sind, sollte Folgendes in jedem Ansichts-Controller platziert werden, der eine bestimmte Ausrichtung benötigt.
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.All.rawValue)
}
Hinweis: Dieser Code wurde mit Swift 1.2 geschrieben
Oft muss ich den aktuell angezeigten View-Controller abrufen. Es könnte bedeuten, dass der View-Controller oben im Stack des aktuellen UINavigationController, der aktuell dargestellte View-Controller usw. angezeigt wird. Ich habe diese Funktion also geschrieben, die die meiste Zeit herausfindet und die Sie in einer UIViewController-Erweiterung verwenden können.
Code in 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
}
}
Nennen Sie es mit: currentViewController()
UIApplication-Erweiterung in Swift 4+ Syntax basierend auf A.Gs Lösung
public 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 {
let moreNavigationController = tab.moreNavigationController
if let top = moreNavigationController.topViewController, top.view.window != nil {
return topViewController(base: top)
} else if let selected = tab.selectedViewController {
return topViewController(base: selected)
}
}
if let presented = base?.presentedViewController {
return topViewController(base: presented)
}
return base
}
}
Beispielnutzung:
if let rootViewController = UIApplication.topViewController() {
//do something with rootViewController
}