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


180

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

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

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


아직 알지 못했습니다. 그러나 내 응용 프로그램에서는 window.rootviewcontroller에 viewcontroller를 할당하지 않습니다. 창에보기를 추가하고 있습니다. 그것이 저의 이유 일 수 있습니다. 그러나 확실하지 않은 ...
Gagan Joshi

@GaganJoshi 위에서 언급 한 이유가 원인이 아닐 수도 있습니다. 심지어 나는 같은 문제에 직면하고 있습니다. 그리고 우리 프로젝트에서 view controller를 window.rootviewcontroller에 할당하고 있습니다.
Rajesh

1
다른 주석은 이것을 rootViewController 및 창 연결에 관한 것과 올바르게 관련 있다고 생각합니다. 나는 그것을 알아 내지 못했지만 네비게이션 컨트롤러 또는 하위 컨트롤러 대신 rootViewController에 컨트롤러를 직접 표시하여 문제를 해결할 수있었습니다.
Rich Waters

답변:


207

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

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

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

[self dismissViewControllerAnimated:YES completion:nil];


이 라인 코드 "[self.view.window.rootViewController presentViewController : viewController animated : YES completion : nil];"와 함께 이미지 선택기를 제시하고 있습니다. 그러나 "[self dismissViewControllerAnimated : YES complete : nil];"행으로 Poicker보기를 해제 할 수 없습니다. dismisscontroller에 대한 모든 다른 옵션
kb920

@keyurbhalodiya 작동하려면 modalView에서 dismissViewController 메소드를 호출해야합니다. 따라서 [viewA.window.rootViewController presentViewController : viewB]를 사용하여 viewA에서 viewB라는보기를 표시 한 경우 viewB에서 예를 들어 [self dismissViewControllerAnimated]를 호출하는 사용자 정의 조치와 ​​연관된 단추를 추가해야합니다. 더 명확합니까?
cdescours

11
iOS 8에서 뷰 컨트롤러를 제공하지 않음
Rajesh Maurya

1
iOS 8 용 : [self.view.window.rootViewController.navigationController
Fede Cugliandolo

31
self.navigationController나를 위해 사용 했습니다.
Brandon Zacharie

62

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

마스터 상세도

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

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

1
[self.view.window.rootViewController.navigationController pushViewController : YOUR_VIEW_CONTROLER 애니메이션 : YES];
Fede Cugliandolo

1
"전체 크기보기가 아닌 작은보기에 대해보기 컨트롤러를 표시했습니다." ... 바로 그거죠. 잘 하셨어요.
Fattie

61

기다립니다 viewDidAppear():

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


9
다시 말해 viewDidLoad()사람들에게 뷰 컨트롤러를 표시하지 마십시오 . 나는이 실수를 너무나 많이했다.
T Blank

감사합니다. viewDidLoad에 끝에 대화 상자를 표시하려고하는 코드가 있습니다.
ArdenDev

애니메이션으로 테스트하지 않는 단위 / 통합 테스트를 실행할 때이 오류가 발생합니다.
mixtly87

21

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


또한 didMoveToParentViewController를 호출하십시오. Pleaes Check ChildViewController 추가 및 제거 : gist.github.com/tomohisa/2897676
Jakehao

@jianzong 마지막 단계를 수행 할 필요가 없다는 것을 기억합니다. 어쨌든, 제안을 위해 추가하십시오. :)
Kjuly

예, 마지막 단계없이 작동합니다. 나는 그것의 목적이 무언가를하기 위해 몇 가지 메소드를 호출하도록 parentViewController에 알리는 것입니다. :)
Jakehao

2
그것은 나를 위해 작동합니다, 다른 컨트롤러에서 하나의 컨트롤러보기를 사용하여 메신저-(컨테이너보기) 프로그래밍 방식으로 추가하지 않았습니다 [self addChildViewController:sampleViewController];. 이제 추가했습니다. 감사합니다
anjnkmr

16

문제는 적절한 뷰 컨트롤러 계층 구조가 없다는 것입니다. 앱의 rootviewcontroller를 설정 한 다음 새보기 컨트롤러를 밀어 올리거나 표시하여 새보기를 표시하십시오. 각 뷰 컨트롤러가 뷰를 관리하도록합니다. tabbarviewcontroller와 같은 컨테이너 뷰 컨트롤러 만 다른 뷰 컨트롤러 뷰를 자체 뷰에 추가해야합니다. 뷰 컨트롤러를 올바르게 사용하는 방법에 대한 자세한 내용은 뷰 컨트롤러 프로그래밍 안내서를 읽으십시오.https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/


14

스위프트 3

이것에 걸려 넘어지는 사람에게는 빠른 답변이 있습니다.

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

9

나는 거의 같은 문제가 있습니다. 그 이유는 다른 컨트롤러에 "일부"컨트롤러를 표시하려고했기 때문에 애니메이션이 완료된 후 컨트롤러를 루트로 설정했습니다. 이 작업이 끝나면 모든 추가 컨트롤러가 경고 메시지를 표시합니다. " 분리 된 뷰 컨트롤러에 뷰 컨트롤러를 표시하지 않는 것이 좋습니다. ". 그리고이 경고를 시작 부분에 프리젠 테이션없이 "일부"컨트롤러를 루트로 설정하면됩니다.

제거 :

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

       [self window].rootViewController = controller;

       [[self window] makeKeyAndVisible];}];

프레젠테이션없이 루트로 만드십시오.

 [[self window] setRootViewController:controller];

1
이것은 정확히 내 문제였습니다. UIModalTransitionStyleCrossDissolve를 제시하고 rootViewController로 만들려고했습니다. 그 후, 다른 모든 프레젠테이션은 주어진 경고 메시지와 함께 실패했습니다. 애니메이션없이 rootViewcontroller로 설정하면 트릭이되었습니다. 감사!
Bernardo Oliveira

7

이것에 대한 해결책 중 하나는 childviewcontroller가있는 경우입니다.

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

해제하려면 동일한 dismissview 컨트롤러를 사용하십시오.

[self dismissViewControllerAnimated:YES completion:nil];

이것은 완벽한 솔루션입니다.


7

[self.navigationController presentViewController:xxx animated:YES completion:nil]iOS 8에서 사용하십시오 .


5

이 코드를 사용해보십시오

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

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

4

TabBarController그것이 TabBarController기본 응용 프로그램 인지에 대해 제시하십시오 .

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

이유 self는 자녀의 자녀 일 수 있으며 TabBarController에서 발표하려고합니다 ChildViewController.


4

예, 다른 뷰에있는 경고 컨트롤러를 표시하면서 동일한 경고 메시지에 직면했습니다. 나중에 다음과 같이 부모보기 컨트롤러에서 경고 컨트롤러를 제시하여 이것을 피했습니다.

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

3

새 컨트롤러를 상위 뷰 컨트롤러의 자식으로 표시 할 뷰 컨트롤러를 추가해야합니다.

MainViewController가 있고 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

3

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

이와 같은 DispatchQueue를 통해 실행하면 나에게 도움이되었습니다. 첫 번째 뷰 컨트롤러의 viewDidLoad에서 호출 된 모달 뷰 컨트롤러에 performSegue를 수행하고 있습니다 (새로운 사용자를위한 첫 번째 시작 화면). 제대로로드되었지만 경고가 생성되었습니다. DispatchQueue 비동기 호출에서 performSegue 호출을 랩하면 경고가 제거됩니다. 감사!
그랜트 노이 펠트

1

시작할 루트 뷰 컨트롤러가 있는지 확인하십시오. 에서 설정할 수 있습니다 didFinishLaunchingWithOptions.

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

1

이 경고에 대한 많은 이유가 있습니다. 내 것은 ViewController에서 모달로 표시되는 다른 segue가 연결되어 있기 때문입니다. 그러나 내가 제시하는 ViewController는 PageViewController에 의해 동적으로 생성됩니다. 이것이 스토리 보드에서 분리 된 이유입니다. 앱으로 인해 충돌이 발생하지 않습니다. 그러나 나는 경고를 침묵시키고 싶다.


1

사용자 정의 탐색 막대가있는이 스레드에 도달했으며이를 통해 AlertViewController를 호출했습니다.

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

당신은 추가해야합니다 Zoomed Image View Controller메인 ViewController의 자식으로 .

(예)

[self addChildViewController:ZoomedImageViewController];

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

[self presentViewController:ZoomedImageViewController];

1

많은 답변이 옳습니다.

  • presentingViewController에 parentViewController가 있는지 확인하십시오.
  • 아니라면 추가해야 할 곳에 추가하십시오
  • 그렇지 않으면 모든 viewController에 부모가있을 때까지 parentViewController에 parentViewController가 재귀 적으로 있는지 확인하십시오.

이 문제는 동료가 AViewController를 BViewController에 추가 할 때 발생했습니다. 어쨌든 그는 AViewController의 뷰를 BViewController의 뷰에 추가합니다.

add bViewController.addChild (aViewController)에 의해 수정되었습니다.


1
감사합니다! 내 Hero.shared.transition 완료 블록에 addChild를 추가하면 내 문제가 완전히 해결되었습니다.
landnbloc

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

귀하의 코드로는 작동하지 Attempt to present <UIAlertController: 0x7fc01a1eb600> on <ViewController: 0x7fc019821e00> whose view is not in the window hierarchy!
않으며이
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.