提问人:Gagan Joshi 提问时间:11/10/2013 最后编辑:NareshGagan Joshi 更新时间:11/21/2023 访问量:149987
警告 :-不建议在分离的视图控制器上显示视图控制器
Warning :-Presenting view controllers on detached view controllers is discouraged
问:
在我的应用程序中,我使用的是导航控制器。稍后,在某些视图中,我用于显示缩放的图像。
此外,我没有使用故事板或笔尖。presentViewController
我仅在 iOS 7 中收到此错误。它在 iOS 6 及更早版本中运行良好:
在分离的视图控制器上显示视图控制器是 气馁
答:
我认为问题在于您没有适当的视图控制器层次结构。设置应用的 rootviewcontroller,然后通过在新视图上推送或显示新视图控制器来显示新视图。让每个视图控制器管理其视图。只有容器视图控制器(如 tabbarviewcontroller)才能将其他视图控制器视图添加到自己的视图中。阅读视图控制器编程指南,了解有关如何正确使用视图控制器的更多信息。https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/
为避免在推送导航中收到警告,您可以直接使用:
[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];
然后在你的模态视图控制器中,当一切都完成后,你可以调用:
[self dismissViewControllerAnimated:YES completion:nil];
评论
self.navigationController
确保您有一个根视图控制器。您可以在 中设置它。didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window setRootViewController:viewController];
}
我有几乎同样的问题。原因是我试图在另一个控制器上呈现“某些”控制器,并且在动画完成后,我将呈现的控制器设置为root。在此操作之后,所有进一步的控制器都会向我显示警告:“不建议在分离的视图控制器上显示视图控制器”。我解决了这个警告,只是将“一些”控制器设置为root,一开始没有任何演示。
删除:
[[self rootController] presentViewController:controller animated:YES completion:^{
[self window].rootViewController = controller;
[[self window] makeKeyAndVisible];}];
只需以 root 身份创建,无需任何演示:
[[self window] setRootViewController:controller];
评论
此警告的原因是我在非全尺寸视图的小视图上呈现视图控制器。下面是我的项目图片。单击上面的四个选项。用户导航到不同的 childviewcontroller 视图。(它的工作方式类似于 tabViewcontroller)。但是 childviewcontroller 包含小尺寸的视图。因此,如果我们从 childviewcontroller 显示视图,它会发出此警告。
为了避免这种情况,您可以在 childviewcontroller 的父级上显示视图
[self.parentViewController presentViewController:viewController animated:YES completion:nil];
评论
其中一个解决方案是,如果你有 childviewcontroller,那么你只需在它的父级上给出
[self.parentViewController presentViewController:viewController animated:YES completion:nil];
对于 dismiss,请使用相同的 dismissview 控制器。
[self dismissViewControllerAnimated:YES completion:nil];
这是完美的解决方案,适用于我。
在 iOS 8 中使用。[self.navigationController presentViewController:xxx animated:YES completion:nil]
就我而言,我添加了一个视图作为子视图,然后尝试从视图(这里是一个实例)显示一个弹出框:sampleViewController
sampleViewController
self
UIViewController
[self.view addSubview:sampleViewController.view];
正确的方法应该如下:
// make sure the vc has been added as a child view controller as well
[self addChildViewController:sampleViewController];
[self.view addSubview:sampleViewController.view];
[sampleViewController didMoveToParentViewController:self];
顺便说一句,这也适用于在表格视图单元格中显示弹出框的情况,您只需要确保表格视图控制器也已添加为子视图控制器。
评论
[self addChildViewController:sampleViewController];
是的,我在另一个视图中显示警报控制器时也遇到了相同的警告消息。后来,我通过从父视图控制器显示警报控制器来避免这种情况,如下所示:
[self.parentViewController presentViewController:alertController animated:YES completion:nil];
俟:viewDidAppear()
如果您尝试在视图实际出现之前显示视图控制器,例如在视图中或更早版本中显示视图,也会出现此错误。
尝试在它之后或内部呈现另一个视图。viewWillAppear()
viewDidAppear()
评论
viewDidLoad()
您需要添加视图控制器,该控制器将新控制器显示为父视图控制器的子控制器。
假设你有 MainViewController,然后添加一个名为 controllerA 的新控制器,然后你希望从 controllerA 提供一个名为 controllerB 的新控制器
你必须写这样的东西:
[self addChildViewController:controllerA]; //self is yourMainViewController
[self.view addsubView:controllerA.view];
在控制器 A 中,您可以在不发出警告的情况下显示新控制器
[self presentViewController:controllerB animated:YES completion:nil]; //self is controllerA
试试这段代码
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>];
[self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];
此警告的原因有很多。我的是因为我有一个从 ViewController 连接到另一个 segue,它将以模式呈现。但是,我演示的 ViewController 是由 PageViewController 动态生成的。这就是它在 Storyboard 中分离的原因。我的应用程序不会因此而崩溃;但我想让警告保持沉默。
斯威夫特 3
对于任何绊倒这一点的人,这里有一个快速的答案。
self.parent?.present(viewController, animated: true, completion: nil)
尝试展示它是否是基于应用程序。TabBarController
TabBarController
[self.tabBarController presentViewController:viewController animated:YES completion:nil];
原因可能是 的子项,而您正试图从 .self
TabBarController
ChildViewController
这取决于你是否要在 UIViewController 类型的任何位置显示警报或类似内容。
您可以使用以下代码示例:
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"Alert" message:@"Example" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:cancelAction];
[[[[[UIApplication sharedApplication] delegate] window] rootViewController] presentViewController:alert animated:true completion:nil];
评论
Attempt to present <UIAlertController: 0x7fc01a1eb600> on <ViewController: 0x7fc019821e00> whose view is not in the window hierarchy!
在 Swift 4.1 和 Xcode 9.4.1 中
解决方案是
DispatchQueue.main.async(execute: {
self.present(alert, animated: true)
})
我是这样写的,我遇到了同样的错误
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
})
alert.addAction(defaultAction)
present(alert, animated: true, completion: nil)
我遇到同样的错误
Presenting view controllers on detached view controllers is discouraged <MyAppName.ViewController: 0x7fa95560Z070>.
完整的解决方案是
let alert = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .default, handler: { action in
})
alert.addAction(defaultAction)
//Made Changes here
DispatchQueue.main.async(execute: {
self.present(alert, animated: true)
})
评论
我到达了这个线程,我有一个自定义导航栏,我通过它调用了一个 AlertViewController。
我不得不将它作为一个孩子添加到我的主视图控制器中。然后我可以在没有任何警告的情况下调用它。
您应该将 your 添加为主 ViewController 的子项。Zoomed Image View Controller
(例如)
[self addChildViewController:ZoomedImageViewController];
然后,你就可以调用 ZoomedImageViewController
[self presentViewController:ZoomedImageViewController];
许多答案都是对的。
- 检查您的 presentingViewController 是否具有 parentViewController。
- 如果没有,请将其添加到应该添加的位置
- 否则,以递归方式检查它的 parentViewController 是否具有 parentViewController,直到每个 viewController 都有 parent
当我的同事将 AViewController 添加到 BViewController 时,我遇到了这个问题。不知何故,他只是将 AViewController 的视图添加到 BViewController 的视图中。
通过添加 bViewController.addChild(aViewController) 修复
评论