wake-up-neo.com

Aktuelle Ansichtssteuerung von AppDelegate?

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.

47
aoakenfo

Wenn Sie UINavigationController in appDelegate verwenden, verwenden Sie seine Eigenschaft topViewController oder visibleViewController

20
beryllium

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.

60
devios1

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

25
Daniel Ryan

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
}
13
A.G

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;
11
Quasar

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 :)

8
MattZ

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

4
Clay Ellis

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()

0
Paolo Musolino

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
}
0
Maverick