来自AppDelegate的当前视图控制器?

时间:2012-01-25 20:16:57

标签: objective-c ios uiviewcontroller

有没有办法从AppDelegate获取当前视图控制器?我知道有rootViewController,但这不是我想要的。

10 个答案:

答案 0 :(得分:60)

如果你的应用的根视图控制器是UINavigationController,你可以这样做:

((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;

同样,如果它是UITabBarController,你可以这样做:

((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;

当然,像这样的显式投射很脏。更好的方法是使用强类型来捕获引用。

答案 1 :(得分:26)

这可能会有所帮助

- (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];
}

Swift版本:

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

取自: https://gist.github.com/snikch/3661188

答案 2 :(得分:20)

如果您将UINavigationController导入appDelegate,请使用其属性topViewControllervisibleViewController

答案 3 :(得分:14)

制作扩展程序:

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

<强>用法:

if let rootViewController = UIApplication.topViewController() {
    //do sth with root view controller
}

答案 4 :(得分:11)

获取appDelegate对象:

MyAppDelegate *tmpDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

铍建议您可以使用UINavigationController的属性来访问当前的视图控制器。

所以代码看起来像:

id myCurrentController = tmpDelegate.myNavigationController.topViewController;

或:

NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;

答案 5 :(得分:8)

您可以通过查找其presentViewController从rootViewController获取当前视图控制器,如下所示:

    $(window).scroll(function (e){

        var scrollTop = $(window).scrollTop();

        $(".panel").each(function() {

            var el         = $(this),
            offset         = el.offset(),
            floatingHeader = $(".floatingHeader", el);

            var visibility = scrollTop > (offset.top - 20)
                             && scrollTop < offset.top + el.height()?
                             "visible" : "hidden";

            floatingHeader.css({"visibility": visibility});

        });
    });

它适用于我。希望它有所帮助:)

答案 6 :(得分:4)

对于使用UINavigationController的任何人而言,他们的默认视图控制器是UIViewController,您可以使用{中的以下内容检查哪个视图控制器处于活动状态(或已显示) {1}}:

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

注意:此代码是使用Swift 1.2编写的

答案 7 :(得分:4)

  

快速解决方案:

 self.window.rootViewController.presentedViewController. 

那应该能满足你的需求。

答案 8 :(得分:0)

我经常需要检索当前显示的视图控制器。它可能意味着视图控制器位于当前UINavigationController的堆栈顶部,当前呈现的视图控制器等。所以我编写了这个函数,它在大多数时候都能找到它,并且你可以在UIViewController扩展中使用它。 / p>

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

currentViewController()

调用它

答案 9 :(得分:0)

基于A.G's solution

Swift 4 + 语法的UIApplication扩展
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
    }
}

样品用量:

if let rootViewController = UIApplication.topViewController() {
     //do something with rootViewController
}