从app delegate获取当前视图控制器(可以使用模态)

Mas*_*son 7 delegates objective-c ios appdelegate

我知道要从app delegate获取当前视图控制器,我可以使用navigationController我为我的应用程序设置的属性.但是,在我的应用程序的许多地方都可以提供模态导航控制器.有没有办法从app委托中检测到这个,因为当前导航控制器将与app委托持有引用的导航控制器不同?

jun*_*jie 9

基于这里要点,我创建了一个类别来获得最顶层的视图控制器,这样调用[[UIApplication sharedApplication] topMostViewController]将为您提供应用程序中最顶层的视图控制器.

这在iOS 8中特别有用,其中UIAlertView并且UIActionSheet已被弃用UIAlertController,需要在最顶层的视图控制器上呈现.

的UIViewController + TopMostViewController.h

#import <UIKit/UIKit.h>

@interface UIViewController (TopMostViewController)

- (UIViewController *)topMostViewController;

@end

@interface UIApplication (TopMostViewController)

- (UIViewController *)topMostViewController;

@end
Run Code Online (Sandbox Code Playgroud)

的UIViewController + TopMostViewController.m

#import "UIViewController+TopMostViewController.h"

@implementation UIViewController (TopMostViewController)

- (UIViewController *)topMostViewController
{
    if (self.presentedViewController == nil)
    {
        return self;
    }
    else if ([self.presentedViewController isKindOfClass:[UINavigationController class]])
    {
        UINavigationController *navigationController = (UINavigationController *)self.presentedViewController;
        UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
        return [lastViewController topMostViewController];
    }

    UIViewController *presentedViewController = (UIViewController *)self.presentedViewController;
    return [presentedViewController topMostViewController];
}

@end

#pragma mark -

@implementation UIApplication (TopMostViewController)

- (UIViewController *)topMostViewController
{
    return [self.keyWindow.rootViewController topMostViewController];
}

@end
Run Code Online (Sandbox Code Playgroud)


zig*_*ear 7

我建议你使用NSNofiticationCenter.

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

//in every ViewController you want to detect
@implementation SomeViewController
...
- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] postNotificationName:@"CurrentViewController" object:nil userInfo:[NSDictionary dictionaryWithObjectsAndKeys:self, @"lastViewController", nil]];
}
...
@end
Run Code Online (Sandbox Code Playgroud)

  • 我所做的是,每次在其viewWillAppear中的NSUserDefaults字段中保存最后一个viewController名称.通过这种方式,我可以访问用户在整个应用中使用的最后一个活动视图. (2认同)

小智 5

Swift 中很棒的解决方案,在 AppDelegate 中实现

func getTopViewController()->UIViewController{
    return topViewControllerWithRootViewController(UIApplication.sharedApplication().keyWindow!.rootViewController!)
}
func topViewControllerWithRootViewController(rootViewController:UIViewController)->UIViewController{
    if rootViewController is UITabBarController{
        let tabBarController = rootViewController as! UITabBarController
        return topViewControllerWithRootViewController(tabBarController.selectedViewController!)
    }
    if rootViewController is UINavigationController{
        let navBarController = rootViewController as! UINavigationController
        return topViewControllerWithRootViewController(navBarController.visibleViewController)
    }
    if let presentedViewController = rootViewController.presentedViewController {
        return topViewControllerWithRootViewController(presentedViewController)
    }
    return rootViewController
}
Run Code Online (Sandbox Code Playgroud)

目标-C

- (UIViewController*)topViewController {
    return [self topViewControllerWithRootViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}

- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
       UITabBarController* tabBarController = (UITabBarController*)rootViewController;
       return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
    } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
      UINavigationController* navigationController = (UINavigationController*)rootViewController;
      return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
     } else if (rootViewController.presentedViewController) {
       UIViewController* presentedViewController = rootViewController.presentedViewController;
       return [self topViewControllerWithRootViewController:presentedViewController];
     } else {
       return rootViewController;
    }
}
Run Code Online (Sandbox Code Playgroud)