ios AppDelegate 的当前视图控制器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9009646/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:30:20  来源:igfitidea点击:

Current view controller from AppDelegate?

objective-ciosuiviewcontroller

提问by aoakenfo

Is there a way to get the current view controller from the AppDelegate? I know there is rootViewController, but that's not what I'm looking for.

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

采纳答案by beryllium

If you have UINavigationController into appDelegate then use its property topViewControlleror visibleViewController

如果你有 UINavigationController 到 appDelegate 然后使用它的属性topViewControllervisibleViewController

回答by devios1

If your app's root view controller is a UINavigationControlleryou can do this:

如果您的应用程序的根视图控制器是 aUINavigationController您可以这样做:

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

Similarly, if it's a UITabBarControlleryou can do this:

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

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

Of course, explicit casting like this is dirty. Better would be to capture the reference yourself using strong types.

当然,像这样的显式转换是肮脏的。最好使用强类型自己捕获引用。

回答by Daniel Ryan

This might help

这可能有帮助

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

Taken from: https://gist.github.com/snikch/3661188

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

回答by A.G

Make an extension:

做一个扩展:

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

Usage:

用法:

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

回答by Quasar

Get the appDelegate object:

获取 appDelegate 对象:

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

As beryllium suggested you can use the UINavigationController's properties to access your current view controller.

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

So the code would look like:

所以代码看起来像:

id myCurrentController = tmpDelegate.myNavigationController.topViewController;

or:

或者:

NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;

回答by MattZ

You can get the current view controller from rootViewController by looking for its presentedViewController, like this:

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

UIViewController *parentViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;

while (parentViewController.presentedViewController != nil){
    parentViewController = parentViewController.presentedViewController;
}
UIViewController *currentViewController = parentViewController;

It works with me. Hope it helps :)

它和我一起工作。希望能帮助到你 :)

回答by Clay Ellis

For anyone notusing a UINavigationControllerbut rather their default view controller is a UIViewControlleryou can check which view controller is active (or presented) with the following in AppDelegate:

对于使用 aUINavigationController而是他们的默认视图控制器是 a 的任何人,UIViewController您可以使用以下内容检查哪个视图控制器处于活动状态(或显示)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)
}

As you can see I'm checking for the current view controller in order to support different interface orientations for specific view controllers. For anyone else interested in using this method to support specific the following should be placed in each view controller that needs a specific orientation.

如您所见,我正在检查当前视图控制器,以支持特定视图控制器的不同界面方向。对于有兴趣使用此方法来支持特定的任何其他人,应将以下内容放置在需要特定方向的每个视图控制器中。

override func supportedInterfaceOrientations() -> Int {
    return Int(UIInterfaceOrientationMask.All.rawValue)
} 

Note:This code was written with Swift 1.2

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

回答by LevinsonTechnologies

Swift Solution:

迅捷解决方案:

 self.window.rootViewController.presentedViewController. 

That should get you what you need.

那应该可以满足您的需求。

回答by Maverick

UIApplication extension in Swift 4+syntax based on A.G's solution

基于AG 解决方案的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
    }
}

Sample usage:

示例用法:

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

回答by Paolo Musolino

Often I need to retrieve the view controller that is currently displayed. It could mean the view controller at the top of the stack of the current UINavigationController, the currently presented view controller, etc. So I wrote this function which figures it out most of the time, and that you can use inside a UIViewController extension.

我经常需要检索当前显示的视图控制器。它可能意味着当前 UINavigationController 堆栈顶部的视图控制器、当前呈现的视图控制器等。所以我编写了这个函数,它在大部分时间都可以计算出来,并且您可以在 UIViewController 扩展中使用它。

Code in Swift 3:

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

Call it with: currentViewController()

调用它: currentViewController()