iphone - 在 AppDelegate.m 中获取当前显示在屏幕上的 UIViewController

标签 iphone ios uiviewcontroller push-notification

屏幕上的当前 UIViewController 需要通过设置一些角标(Badge) View 来响应来自 APNs 的推送通知。但是我怎样才能在 AppDelegate.m 的方法application:didReceiveRemoteNotification: 中获取 UIViewController

我尝试使用 self.window.rootViewController 获取当前显示的 UIViewController,它可能是 UINavigationViewController 或其他类型的 View Controller 。我发现 UINavigationViewControllervisibleViewController 属性可用于在屏幕上获取 UIViewController。但是,如果它不是 UINavigationViewController,我该怎么办?

感谢任何帮助!相关代码如下。

AppDelegate.m

...
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

    //I would like to find out which view controller is on the screen here.

    UIViewController *vc = [(UINavigationViewController *)self.window.rootViewController visibleViewController];
    [vc performSelector:@selector(handleThePushNotification:) withObject:userInfo];
}
...

ViewControllerA.m

- (void)handleThePushNotification:(NSDictionary *)userInfo{

    //set some badge view here

}

最佳答案

我一直喜欢涉及类别的解决方案,因为它们是固定的并且可以轻松重复使用。

所以我在 UIWindow 上创建了一个类别。您现在可以在 UIWindow 上调用 visibleViewController,这将通过向下搜索 Controller 层次结构为您提供可见 View Controller 。如果您使用导航和/或选项卡栏 Controller ,这会起作用。如果您有其他类型的 Controller 建议,请告诉我,我可以添加。

UIWindow+PazLabs.h(头文件)

#import <UIKit/UIKit.h>

@interface UIWindow (PazLabs)

- (UIViewController *) visibleViewController;

@end

UIWindow+PazLabs.m(实现文件)

#import "UIWindow+PazLabs.h"

@implementation UIWindow (PazLabs)

- (UIViewController *)visibleViewController {
    UIViewController *rootViewController = self.rootViewController;
    return [UIWindow getVisibleViewControllerFrom:rootViewController];
}

+ (UIViewController *) getVisibleViewControllerFrom:(UIViewController *) vc {
    if ([vc isKindOfClass:[UINavigationController class]]) {
        return [UIWindow getVisibleViewControllerFrom:[((UINavigationController *) vc) visibleViewController]];
    } else if ([vc isKindOfClass:[UITabBarController class]]) {
        return [UIWindow getVisibleViewControllerFrom:[((UITabBarController *) vc) selectedViewController]];
    } else {
        if (vc.presentedViewController) {
            return [UIWindow getVisibleViewControllerFrom:vc.presentedViewController];
        } else {
            return vc;
        }
    }
}

@end

Swift 版本

public extension UIWindow {
    public var visibleViewController: UIViewController? {
        return UIWindow.getVisibleViewControllerFrom(self.rootViewController)
    }

    public static func getVisibleViewControllerFrom(_ vc: UIViewController?) -> UIViewController? {
        if let nc = vc as? UINavigationController {
            return UIWindow.getVisibleViewControllerFrom(nc.visibleViewController)
        } else if let tc = vc as? UITabBarController {
            return UIWindow.getVisibleViewControllerFrom(tc.selectedViewController)
        } else {
            if let pvc = vc?.presentedViewController {
                return UIWindow.getVisibleViewControllerFrom(pvc)
            } else {
                return vc
            }
        }
    }
}

关于iphone - 在 AppDelegate.m 中获取当前显示在屏幕上的 UIViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11637709/

相关文章:

ios - View Controller 无法找到带有标识符的 Segue

php - 从 iPhone 应用程序调用远程 php 函数

ios - 在哪里可以获取适用于我的 iOS 项目的 Appium 兼容 iOS 应用程序文件?

iphone - AdWhirl 和 ARC

ios - MKMarkerAnnotationView 不显示标注

c# - Base64 解码带有 ISO-8859-1 字符集的字符串并将其保存到 NSData

objective-c - 是否存在ModalViewController : add the view controller to the stack?

uitableview - 如何在 .xib 文件上创建的 UIViewController 中设置 UITableView

iphone - 如何使用可拉伸(stretch)图像创建 UIImageView

iphone - 向导航栏添加按钮