如何解决(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 中,我是 attempting to access the navigation stack I am currently on。
-
这两个例子的最后一行,我正在尝试push the new VC on top of the stack。
我的结果:
- 示例 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
(上面可能有错别字,但这就是想法)
,-
UIViewController 上的 navigationController 属性可以为 null,因此它可能返回 nil。
-
UINavigationController 上的 topViewController 属性也是可为空的,并返回一个 UIViewController?,而不是特定的类。简单地将任何 UIViewController 转换为 ViewController 是不安全的,因此您应该检查 isKindOfClass。
-
同样的事情适用于 rootViewController,它可能并不总是一个 TabBarController,所以无条件地投射它是不安全的。
- 另外,发现如果 rootViewController 是 UITableViewController 类型,则 navigationController 为零。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。