Ios 从应用程序委托获取当前视图控制器

Ios 从应用程序委托获取当前视图控制器,ios,objective-c,delegates,appdelegate,Ios,Objective C,Delegates,Appdelegate,我是ios新手。我需要从app delegate了解当前视图控制器。。我对此一无所知,也不知道如何实施。我正在使用此代码来实现此操作,但它返回空值。 我跟踪了这个链接- 需要帮助。这取决于您如何设置UI。如果以这种方式进行设置,则可以获取rootViewController并在层次结构中移动 UIViewController *vc = self.window.rootViewController; 我正在使用此代码- //in AppDelegate: @interface AppDele

我是ios新手。我需要从app delegate了解当前视图控制器。。我对此一无所知,也不知道如何实施。我正在使用此代码来实现此操作,但它返回空值。 我跟踪了这个链接-
需要帮助。

这取决于您如何设置UI。如果以这种方式进行设置,则可以获取rootViewController并在层次结构中移动

UIViewController *vc = self.window.rootViewController;

我正在使用此代码-

//in AppDelegate:

@interface AppDelegate()

{

    id lastViewController;

}


@implementation AppDelegate

-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions

{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCurrentViewController) name:@"CurrentViewController" object:nil];


}

-(void)handleCurrentViewController:(NSNotification *)notification
 {

    if([[notification userInfo] objectForKey:@"lastViewController"])
   {

        lastViewController = [[notification userInfo] objectForKey:@"lastViewController"];

    }
}

-(void)applicationDidEnterBackground:(UIApplication *)application
{  

    NSLog(@"last view controller is %@", [(UIViewController *)lastViewController class]);

}

@end
//在每个要检测的ViewController中

@implementation SomeViewController

-(void) viewWillDisappear:(BOOL)animated 
{
    [super viewWillDisappear:animated];

    [[NSNotificationCenter defaultCenter] postNotificationName:@"CurrentViewController" object:nil userInfo:[NSDictionary dictionaryWithObjectsAndKeys:self, @"lastViewController", nil]];

}

这就是我用来查找用户最有可能与之交互的当前视图控制器的方法:

UIViewController+Utils.h

#import <UIKit/UIKit.h>

@interface UIViewController (Utils)

+(UIViewController*) currentViewController;

@end
然后,每当我需要应用程序中任何位置的当前视图控制器时,只需使用:

[UIViewController currentViewController]

以下是swift中的一些类/静态函数,我将它们保存在实用程序类中,可以帮助您:

// Returns the most recently presented UIViewController (visible)
class func getCurrentViewController() -> UIViewController? {

    // If the root view is a navigation controller, we can just return the visible ViewController
    if let navigationController = getNavigationController() {

        return navigationController.visibleViewController
    }

    // Otherwise, we must get the root UIViewController and iterate through presented views
    if let rootController = UIApplication.shared.keyWindow?.rootViewController {

        var currentController: UIViewController! = rootController

        // Each ViewController keeps track of the view it has presented, so we
        // can move from the head to the tail, which will always be the current view
        while( currentController.presentedViewController != nil ) {

            currentController = currentController.presentedViewController
        }
        return currentController
    }
    return nil
}

// Returns the navigation controller if it exists
class func getNavigationController() -> UINavigationController? {

    if let navigationController = UIApplication.shared.keyWindow?.rootViewController  {

        return navigationController as? UINavigationController
    }
    return nil
}

这帮助我找到了可视视图控制器。我搜索了现有的方法,但没有找到任何方法。所以我写了我自己的自定义一个

-(id)getCurrentViewController
{
    id WindowRootVC = [[[[UIApplication sharedApplication] delegate] window] rootViewController];

    id currentViewController = [self findTopViewController:WindowRootVC];

    return currentViewController;
}

-(id)findTopViewController:(id)inController
{
    /* if ur using any Customs classes, do like this.
     * Here SlideNavigationController is a subclass of UINavigationController.
     * And ensure you check the custom classes before native controllers , if u have any in your hierarchy.
    if ([inController isKindOfClass:[SlideNavigationController class]])
    {
        return [self findTopViewController:[inController visibleViewController]];
    }
    else */
    if ([inController isKindOfClass:[UITabBarController class]])
    {
        return [self findTopViewController:[inController selectedViewController]];
    }
    else if ([inController isKindOfClass:[UINavigationController class]])
    {
        return [self findTopViewController:[inController visibleViewController]];
    }
    else if ([inController isKindOfClass:[UIViewController class]])
    {
        return inController;
    }
    else
    {
        NSLog(@"Unhandled ViewController class : %@",inController);
        return nil;
    }
}
和样本使用:

-(void)someMethod
{
    id currentVC = [self getCurrentViewController];
        if (currentVC)
        {
            NSLog(@"currentVC :%@",currentVC);
        }
}

JV360伟大答案的快速版本, (我去掉了一些多余的回报,我认为Swift更具可读性)

你的代表

    guard let rvc = self.window?.rootViewController else {
        return
    }
    if let vc = getCurrentViewController(rvc) {
        // do your stuff here
    }

我得到根控制器,然后遍历所提供的VC:

 UIViewController *current = [UIApplication sharedApplication].keyWindow.rootViewController;

while (current.presentedViewController) {
    current = current.presentedViewController;
}
//now you can use current, for example to present an alert view controller:
[current presentViewController:alert animated:YES completion:nil];

|*|从导航视图控制器获取可见视图控制器

let NavVccVar = UIApplication.sharedApplication().keyWindow?.rootViewController as! UINavigationController
let ShnSrnVar = NavVccVar.visibleViewController
let NavVccVar = UIApplication.sharedApplication().keyWindow?.rootViewController as! UINavigationController
NavVccVar.visibleViewController!.presentViewController(NamVccVar, animated: true, completion: nil)

|*|从可见视图控制器显示

let NavVccVar = UIApplication.sharedApplication().keyWindow?.rootViewController as! UINavigationController
let ShnSrnVar = NavVccVar.visibleViewController
let NavVccVar = UIApplication.sharedApplication().keyWindow?.rootViewController as! UINavigationController
NavVccVar.visibleViewController!.presentViewController(NamVccVar, animated: true, completion: nil)

这是我尝试过的最好的解决方案

+ (UIViewController*) topMostController
{
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }

    return topController;
}

我发现了这一点,它适用于所有类型的Segue和view控制器。它很简单,也很短,很好

+(UIViewController*)getTopController{ UIViewController*topViewController=[UIApplication sharedApplication].keyWindow.rootViewController

while (topViewController.presentedViewController) {
    topViewController = topViewController.presentedViewController;
}

return topViewController; }

您使用的是导航控制器吗?请发布您的代码以更好地理解我是这样获得视图控制器名称的-最后一个视图控制器是vc==但我想要视图控制器的名称。如果您在这之后,并且您想要控制器的名称,请尝试id vc=self.window.rootViewController;NSLog(@“控制器名称:%@,[vc类]);我成功地使用了它,并对其进行了修改以使其编译。需要进行一些重新排列。@alaxandermiller,我如何使用这些来获取作为字符串的viewcontroller名称?
while (topViewController.presentedViewController) {
    topViewController = topViewController.presentedViewController;
}

return topViewController; }