警告:不建议在分离的视图控制器上显示视图控制器

时间:2013-11-10 14:19:29

标签: ios iphone ios7 warnings

在我的应用中,我使用的是导航控制器。稍后在某些视图中我使用presentViewController来显示缩放的图像。 我也没有使用故事板或笔尖。

我仅在iOS 7中收到此错误。它在iOS 6及更早版本中运行良好:

  

在分离的视图控制器上呈现视图控制器是   泄气

19 个答案:

答案 0 :(得分:199)

为避免在推送导航中收到警告,您可以直接使用:

[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];

然后在你的模态视图控制器中,当一切都完成后,你可以调用:

[self dismissViewControllerAnimated:YES completion:nil];

答案 1 :(得分:59)

这个警告的原因是我在一个不是全尺寸视图的小视图上呈现了一个视图控制器。以下是我的项目的图像。点击上面的四个选项。用户导航到不同的childviewcontroller的视图。(它的工作方式类似于tabViewcontroller)。但是childviewcontroller包含小尺寸的视图。因此,如果我们从childviewcontroller提供一个视图,它会发出此警告。

master detail view

为避免这种情况,您可以在childviewcontroller的父级

上显示一个视图
  [self.parentViewController presentViewController:viewController animated:YES completion:nil];

答案 2 :(得分:48)

等待viewDidAppear()

如果您在视图实际显示之前尝试显示视图控制器,也会出现此错误,例如在viewWillAppear()或更早版本中显示视图。 尝试在viewDidAppear()之后或其中显示另一个视图。

答案 3 :(得分:18)

在我的情况下,我将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];

B.t.w。,这也适用于弹出形式为tableview单元格的情况,您只需要确保将tableview控制器添加为子视图控制器。

答案 4 :(得分:16)

我认为问题在于您没有合适的视图控制器层次结构。设置应用程序的rootviewcontroller,然后通过在其上推送或显示新视图控制器来显示新视图。让每个视图控制器管理他们的视图。只有容器视图控制器(如tabbarviewcontroller)才能将其他视图控制器视图添加到自己的视图中。阅读视图控制器编程指南,了解有关如何正确使用视图控制器的更多信息。 https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/

答案 5 :(得分:9)

我有几乎相同的问题。原因是我试图在另一个上呈现“一些”控制器,并且在动画完成后我将设置的控制器设置为root。在此操作之后,所有其他控制器都会向我发出警告:“不建议在分离的视图控制器上显示视图控制器”。我解决了这个警告只是将“some”控制器设置为root而没有任何演示文稿。

移除:

[[self rootController] presentViewController:controller animated:YES completion:^{

       [self window].rootViewController = controller;

       [[self window] makeKeyAndVisible];}];

在没有任何演示的情况下以root身份制作:

 [[self window] setRootViewController:controller];

答案 6 :(得分:8)

解决这个问题的方法之一就是如果你有childviewcontroller所以你只需通过给定的

在其父级上呈现viewviewcontroller
[self.parentViewController presentViewController:viewController animated:YES completion:nil];

对于解雇使用相同的解雇视图控制器。

[self dismissViewControllerAnimated:YES completion:nil];

这对我来说是完美的解决方案。

答案 7 :(得分:8)

Swift 3

对于任何磕磕绊绊的人来说,这是一个快捷的答案。

self.parent?.present(viewController, animated: true, completion: nil)

答案 8 :(得分:6)

在iOS 8中使用[self.navigationController presentViewController:xxx animated:YES completion:nil]

答案 9 :(得分:5)

试试此代码

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>];

[self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];

答案 10 :(得分:3)

是的,我在显示另一个视图中的警报控制器时也遇到了相同的警告消息。稍后我通过从父视图控制器显示警报控制器来避免这种情况,如下所示:

[self.parentViewController presentViewController:alertController animated:YES completion:nil];

答案 11 :(得分:3)

您需要添加视图控制器,将新控制器显示为父视图控制器的子控件。

让我们假设您拥有yourMainViewController,然后添加一个名为controllerA的新控制器,然后您想要从controllerA提供一个名为controllerB的新控制器

你必须写下这样的东西:

[self addChildViewController:controllerA]; //self is yourMainViewController
[self.view addsubView:controllerA.view]; 

并且在controllerA中,您可以在没有警告的情况下显示新控制器

[self presentViewController:controllerB animated:YES completion:nil]; //self is controllerA

答案 12 :(得分:2)

如果它是基于TabBarController的应用,请尝试在TabBarController上展示。

[self.tabBarController presentViewController:viewController animated:YES completion:nil];

原因可能selfTabBarController的孩子而你正试图从ChildViewController出示。

答案 13 :(得分:1)

确保您有一个根视图控制器。您可以在didFinishLaunchingWithOptions

中进行设置
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    [window setRootViewController:viewController];
}

答案 14 :(得分:1)

此警告的原因很多。我的是因为我有一个从ViewController连接到另一个将以模态方式呈现的segue。但是,我呈现的ViewController是由PageViewController动态生成的。这就是故事板中分离的原因。因为它,我的应用程序不会崩溃;但是我想要警告这个警告。

答案 15 :(得分:1)

许多答案都是正确的。

  • 检查您的presentingViewController是否具有parentViewController。
  • 如果否,请将其添加到应添加的位置
  • 否则,请递归检查它的parentViewController是否具有parentViewController,直到每个viewController都具有父视图

当我的同事向BViewController添加AViewController时,发生了此问题。不知何故,他只是将AViewController的视图添加到BViewController的视图。

已通过添加bViewController.addChild(aViewController)

修复

答案 16 :(得分:0)

这取决于你是否想在任何类型的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];

答案 17 :(得分:0)

在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)
})

答案 18 :(得分:0)

我到达了这个线程,那里有一个自定义导航栏,并且正在通过它调用AlertViewController。

我必须将其作为子级添加到我的主视图控制器中。然后我可以在没有任何警告的情况下称呼它。

您应该将Zoomed Image View Controller添加为主ViewController的子代。

(例如)

[self addChildViewController:ZoomedImageViewController];

然后您就可以调用ZoomedImageViewController

[self presentViewController:ZoomedImageViewController];