IT story

경고 : 분리 된 뷰 컨트롤러에서 뷰 컨트롤러를 표시하지 않는 것이 좋습니다.

hot-time 2020. 5. 25. 08:07
반응형

경고 : 분리 된 뷰 컨트롤러에서 뷰 컨트롤러를 표시하지 않는 것이 좋습니다.


내 앱에서 탐색 컨트롤러를 사용하고 있습니다. 나중에 일부보기 presentViewController에서 확대 된 이미지를 보여주기 위해 사용 하고 있습니다. 또한 스토리 보드 또는 펜촉을 사용하지 않습니다.

iOS 7에서만이 오류가 발생합니다. iOS 6 및 이전 버전에서 잘 작동합니다.

분리 된 뷰 컨트롤러에 뷰 컨트롤러를 표시하지 않는 것이 좋습니다.


푸시 탐색에서 경고가 표시되지 않도록하려면 다음을 직접 사용할 수 있습니다.

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

그런 다음 모달보기 컨트롤러에서 모든 것이 끝나면 다음을 호출하면됩니다.

[self dismissViewControllerAnimated:YES completion:nil];


이 경고의 이유는 전체 크기가 아닌 작은보기에보기 컨트롤러를 표시했기 때문입니다. 아래는 내 프로젝트의 이미지입니다. 위의 네 가지 옵션을 클릭하십시오. 사용자는 다른 childviewcontroller의보기로 이동합니다 (tabViewcontroller처럼 작동합니다). 그러나 childviewcontroller에는 작은 크기의보기가 포함되어 있습니다. 따라서 childviewcontroller에서보기를 제시하면이 경고가 나타납니다.

마스터 상세도

이것을 피하기 위해 childviewcontroller의 부모에 대한 견해를 제시 할 수 있습니다

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

기다립니다 viewDidAppear():

이 오류는보기가 실제로 나타나기 전에보기 제어기를 표시하려고하는 경우에도 발생할 수 있습니다 (예 :보기를 viewWillAppear()이전 또는 이전에 표시). 그 이후 viewDidAppear()또는 내부에 다른 견해를 제시 하십시오.


내 경우에는 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];

Btw, 이것은 테이블 뷰 셀에서 팝 오버를 나타내는 경우에도 작동합니다. 테이블 뷰 컨트롤러가 하위 뷰 컨트롤러로 추가되었는지 확인하면됩니다.


I think that the problem is that you do not have a proper view controller hierarchy. Set the rootviewcontroller of the app and then show new views by pushing or presenting new view controllers on them. Let each view controller manage their views. Only container view controllers, like the tabbarviewcontroller, should ever add other view controllers views to their own views. Read the view controllers programming guide to learn more on how to use view controllers properly. https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/


I have almost the same problem. The reason was that I tried to present "some" controller on another and after animation was completed I was setting presented controller as root. After this operation all further controllers presenting bring me to the warning: "Presenting view controllers on detached view controllers is discouraged". And I solve this warning just settings "some" controller as root without any presentation at the begin.

Removed:

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

       [self window].rootViewController = controller;

       [[self window] makeKeyAndVisible];}];

Just make as root without any presentation:

 [[self window] setRootViewController:controller];

Swift 3

For anyone stumbling on this, here is the swift answer.

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

One of the solution to this is if you have childviewcontroller So you simply presentviewcontroller on its parent by given

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

And for dismiss use the same dismissview controller.

[self dismissViewControllerAnimated:YES completion:nil];

This is perfect solution works for me.


Use [self.navigationController presentViewController:xxx animated:YES completion:nil] in iOS 8.


Try this code

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

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

you need to add the view controller that will present the new controller as a child of the parent view controller.

Let's say you have yourMainViewController, then you add a new controller called controllerA, and then you want to present a new controller called controllerB from controllerA

you have to write something like this:

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

and within controllerA you can present the new controller without warnings

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

Try presenting on TabBarController if it is a TabBarController based app .

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

Reason could be self is child of TabBarController and you are trying to present from a ChildViewController.


Yes, I also faced the same warning message while displaying an Alert controller which was in another view. Later on I avoided this by presenting the alert controller from the parent view controller as below:

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

Make sure you have a root view controller to start with. You can set it in didFinishLaunchingWithOptions.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    [window setRootViewController:viewController];
}

Lots of reasons for this warning. Mine is because I have a segue connected from a ViewController to another that will be presented modally. But, the ViewController I am presenting from is being dynamically generated by a PageViewController. Which is why it is detached in the Storyboard. My app isn't going to crash because of it; but I would like to silence the warning.


In Swift 4.1 and Xcode 9.4.1

The solution is

DispatchQueue.main.async(execute: {
    self.present(alert, animated: true)
})

If write like this i'm getting same error

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) 

I'm getting same error

Presenting view controllers on detached view controllers is discouraged <MyAppName.ViewController: 0x7fa95560Z070>.

Complete solution is

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

It depends if you want to show your alert or something similar in anywhere of kind UIViewController.

You can use this code example:

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];

I reached on this thread where I have a Custom Navigation Bar and I was calling an AlertViewController through it.

메인 뷰 컨트롤러에 자식으로 추가해야했습니다. 그런 다음 경고없이 present라고 부를 수 있습니다.

Zoomed Image View Controller기본 ViewController의 하위 항목으로 추가해야합니다 .

(예)

[self addChildViewController:ZoomedImageViewController];

그런 다음 ZoomedImageViewController를 호출 할 수 있습니다

[self presentViewController:ZoomedImageViewController];

참고 URL : https://stackoverflow.com/questions/19890761/warning-presenting-view-controllers-on-detached-view-controllers-is-discourage

반응형