[英]Current view controller from AppDelegate?
有没有办法从 AppDelegate 获取当前视图控制器? 我知道有 rootViewController,但这不是我要找的。
如果您的应用程序的根视图控制器是UINavigationController
您可以这样做:
((UINavigationController*)appDelegate.window.rootViewController).visibleViewController;
同样,如果它是一个UITabBarController
你可以这样做:
((UITabBarController*)appDelegate.window.rootViewController).selectedViewController;
当然,像这样的显式铸造很脏。 更好的方法是使用强类型捕获引用。
这可能有所帮助
- (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
}
}
如果你有UINavigationController到appDelegate然后使用它的属性topViewController或visibleViewController
进行扩展:
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
}
获取appDelegate对象:
MyAppDelegate *tmpDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
由于beryllium建议您可以使用UINavigationController的属性来访问当前的视图控制器。
所以代码看起来像:
id myCurrentController = tmpDelegate.myNavigationController.topViewController;
要么:
NSArray *myCurrentViewControllers = tmpDelegate.myNavigationController.viewControllers;
您可以通过查找其presentViewController从rootViewController获取当前视图控制器,如下所示:
UIViewController *parentViewController = [[[UIApplication sharedApplication] delegate] window].rootViewController;
while (parentViewController.presentedViewController != nil){
parentViewController = parentViewController.presentedViewController;
}
UIViewController *currentViewController = parentViewController;
它适用于我。 希望能帮助到你 :)
对于没有使用UINavigationController
,而是他们的默认视图控制器是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)
}
如您所见,我正在检查当前的视图控制器,以支持特定视图控制器的不同接口方向。 对于任何对使用此方法支持特定内容感兴趣的人,应将其放置在需要特定方向的每个视图控制器中。
override func supportedInterfaceOrientations() -> Int {
return Int(UIInterfaceOrientationMask.All.rawValue)
}
注意:此代码是使用Swift 1.2编写的
Swift解决方案:
self.window.rootViewController.presentedViewController.
这应该可以满足你的需求。
基于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
}
}
样品用法:
if let rootViewController = UIApplication.topViewController() {
//do something with rootViewController
}
我经常需要检索当前显示的视图控制器。 它可能意味着视图控制器位于当前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()
如果有人想要目标 C。
全局管理器
//
// 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
// 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];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.