微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

(Objective-C) 通过 window.rootView 和 keyWindow 访问导航栈的区别

如何解决(Objective-C) 通过 window.rootView 和 keyWindow 访问导航栈的区别

有谁知道有什么区别

TabBarController* tabBar = (TabBarController *)_window.rootViewController;
UINavigationController* navigationController = tabBar.selectedViewController;
ViewController* initialViewController = (ViewController *)navigationController.topViewController;

还有这个

UINavigationController* navigationController = [UIApplication sharedApplication].keyWindow.rootViewController.navigationController;

ViewController* initialViewController = (ViewController *)navigationController.topViewController;

我的假设:

我的结果:

  • 示例 A 成功将我的新 VC 推送到堆栈,而示例 B 没有

抛开设计原则(示例 B 现在看起来很笨拙,但到目前为止我只有这些),我真的不明白这两个示例的区别,它们不应该执行相同的操作吗?谁能解释一下为什么这些不同?

解决方法

navigationController 方法将返回一个 parent 视图控制器,最近的父 UINavigationController。在您的情况下,看起来好像根视图控制器是一个 UITabBarController,每个选项卡中都有一个 UINavigationController。在标签控制器上调用 -navigationController 将返回 nil,因为它没有父视图控制器(实际上,它是根)。

如果您的应用程序中有多个窗口,则 -keyWindow 可以更改。该方法在 iOS 13 中也已弃用,因为现在可以有多个窗口场景,因此如果您知道要从哪个特定窗口开始,最好使用它,而不是从 UIApplication 开始并向下钻取。>

编辑:如果目标是展示一个新的视图控制器,你可以从根视图控制器开始,沿着所展示的视图控制器向上展示你的新视图控制器。

@implementation UIViewController (MyOvertop)

- (void)my_presentOvertopViewController:(UIViewController *)other animated:(BOOL)animated completion:(void (^ _Nullable)(void))completion
{
    UIViewController *topmost = self;

    while (topmost.presentedViewController &&
           ![topmost.presentedViewController isBeingDismissed])
    {
        topmost = topmost.presentedViewController;
    }

    if (topmost.transitionCoordinator) {
        // transition already going on,wait til it's done and try again
        [topmost.transitionCoordinator animateAlongsideTransition:nil completion:^(id context) {
            dispatch_async(dispatch_get_main_queue(),^{
                [self my_presentOvertopViewController:vc animated:animated completion:completion];
            });
        }];
        return;
    }

    if (topmost != other) {
        [topmost presentViewController:other animated:animated completion:completion];
    }
}

@end

(上面可能有错别字,但这就是想法)

,
  1. UIViewController 上的 navigationController 属性可以为 null,因此它可能返回 nil。

  2. UINavigationController 上的 topViewController 属性也是可为空的,并返回一个 UIViewController?,而不是特定的类。简单地将任何 UIViewController 转换为 ViewController 是不安全的,因此您应该检查 isKindOfClass。

  3. 同样的事情适用于 rootViewController,它可能并不总是一个 TabBarController,所以无条件地投射它是不安全的。

  • 另外,发现如果 rootViewController 是 UITableViewController 类型,则 navigationController 为零。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。