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

发布于 2024-12-29 00:21:57 字数 69 浏览 2 评论 0原文

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

猫瑾少女 2025-01-05 00:21:57

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

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

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

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

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

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

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

Similarly, if it's a UITabBarController you can do this:

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

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

内心旳酸楚 2025-01-05 00:21:57

这可能对

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

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

戏蝶舞 2025-01-05 00:21:57

如果您将 UINavigationController 放入 appDelegate 中,则使用其属性 topViewControllervisibleViewController

If you have UINavigationController into appDelegate then use its property topViewController or visibleViewController

多情出卖 2025-01-05 00:21:57

进行扩展:

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
}

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
}
行雁书 2025-01-05 00:21:57

获取 appDelegate 对象:

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

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

所以代码看起来像:

id myCurrentController = tmpDelegate.myNavigationController.topViewController;

或:

NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;

Get the appDelegate object:

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

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

So the code would look like:

id myCurrentController = tmpDelegate.myNavigationController.topViewController;

or:

NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;
内心激荡 2025-01-05 00:21:57

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

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

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

它与我一起工作。希望它有帮助:)

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

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

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

It works with me. Hope it helps :)

凉城 2025-01-05 00:21:57

对于任何使用UINavigationController但其默认视图控制器是UIViewController的人,您可以使用以下命令检查哪个视图控制器处于活动状态(或呈现) 正如您所看到的,

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

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

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

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

For anyone not using a UINavigationControllerbut rather their default view controller is a UIViewController you can check which view controller is active (or presented) with the following in 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

小…红帽 2025-01-05 00:21:57

UIApplication 扩展采用 Swift 4+ 语法,基于 AG 的解决方案

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
}

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

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
}
淡淡の花香 2025-01-05 00:21:57

快速解决方案:

 self.window.rootViewController.presentedViewController. 

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

Swift Solution:

 self.window.rootViewController.presentedViewController. 

That should get you what you need.

哥,最终变帅啦 2025-01-05 00:21:57

我经常需要检索当前显示的视图控制器。它可能意味着当前 UINavigationController 堆栈顶部的视图控制器、当前呈现的视图控制器等。所以我编写了这个函数,它在大多数情况下都能解决这个问题,并且您可以在 UIViewController 扩展中使用它。

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

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.

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

Call it with: currentViewController()

清风疏影 2025-01-05 00:21:57

如果有人想要 Objective C。

GlobalManager.h

//
//  GlobalManager.h
//  Communicator
//
//  Created by Mushrankhan Pathan on 21/10/21.
//  Copyright © 2021 Ribbideo. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface GlobalManager : NSObject

typedef void (^ ActionBlock)(void);

+(UIViewController*)currentController;
+(UIViewController*)currentController:(UIViewController*) baseController;

@end

NS_ASSUME_NONNULL_END

GlobalManager.m

//
//  GlobalManager.m
//  Communicator
//
//  Created by Mushrankhan Pathan on 21/10/21.
//  Copyright © 2021 Ribbideo. All rights reserved.
//

#import "GlobalManager.h"

@implementation GlobalManager

+(UIViewController*)currentController
{
    UIViewController *base = UIApplication.sharedApplication.keyWindow.rootViewController;
    return [GlobalManager currentController:base];
}

+(UIViewController*)currentController:(UIViewController*) baseController
{
    if ([baseController isKindOfClass:[UINavigationController class]]) {
        return [GlobalManager currentController:((UINavigationController*)baseController).visibleViewController];
    }
    
    if ([baseController isKindOfClass:[UITabBarController class]]) {
        UINavigationController* moreNavigationController = ((UITabBarController*)baseController).moreNavigationController;
        UIViewController* top = moreNavigationController.topViewController;
        if (top.view.window != nil) {
            return [GlobalManager currentController:top];
        }
        UIViewController* selectedViewController = ((UITabBarController*)baseController).selectedViewController;
        if (selectedViewController != nil) {
            return [GlobalManager currentController:selectedViewController];
        }
    }
    
    if (baseController.presentedViewController != nil) {
        return [GlobalManager currentController:baseController.presentedViewController];
    }
    
    return baseController;
}

@end

如何使用。

UIViewController *currentVC = [GlobalManager currentController];

If anyone wants in Objective C.

GlobalManager.h

//
//  GlobalManager.h
//  Communicator
//
//  Created by Mushrankhan Pathan on 21/10/21.
//  Copyright © 2021 Ribbideo. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface GlobalManager : NSObject

typedef void (^ ActionBlock)(void);

+(UIViewController*)currentController;
+(UIViewController*)currentController:(UIViewController*) baseController;

@end

NS_ASSUME_NONNULL_END

GlobalManager.m

//
//  GlobalManager.m
//  Communicator
//
//  Created by Mushrankhan Pathan on 21/10/21.
//  Copyright © 2021 Ribbideo. All rights reserved.
//

#import "GlobalManager.h"

@implementation GlobalManager

+(UIViewController*)currentController
{
    UIViewController *base = UIApplication.sharedApplication.keyWindow.rootViewController;
    return [GlobalManager currentController:base];
}

+(UIViewController*)currentController:(UIViewController*) baseController
{
    if ([baseController isKindOfClass:[UINavigationController class]]) {
        return [GlobalManager currentController:((UINavigationController*)baseController).visibleViewController];
    }
    
    if ([baseController isKindOfClass:[UITabBarController class]]) {
        UINavigationController* moreNavigationController = ((UITabBarController*)baseController).moreNavigationController;
        UIViewController* top = moreNavigationController.topViewController;
        if (top.view.window != nil) {
            return [GlobalManager currentController:top];
        }
        UIViewController* selectedViewController = ((UITabBarController*)baseController).selectedViewController;
        if (selectedViewController != nil) {
            return [GlobalManager currentController:selectedViewController];
        }
    }
    
    if (baseController.presentedViewController != nil) {
        return [GlobalManager currentController:baseController.presentedViewController];
    }
    
    return baseController;
}

@end

How to use.

UIViewController *currentVC = [GlobalManager currentController];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文