私のアプリでは、ナビゲーションコントローラを使用しています。後でいくつかのビューで私はズーム画像を表示するためにpresentViewController
を使用しています。ストーリーボードやペン先も使用していません。
私はiOS 7でのみこのエラーを受けています。 iOS 6以前ではうまく動作します。
切り離されたView ControllerにView Controllerを表示することはお勧めできません。
これに対する解決策の一つはあなたがchildviewcontrollerを持っている場合です。
[self.parentViewController presentViewController:viewController animated:YES completion:nil];
そして却下のために同じ却下ビューコントローラを使用してください。
[self dismissViewControllerAnimated:YES completion:nil];
これは完璧な解決策です。
プッシュナビゲーションで警告が表示されないようにするには、直接使用できます。
[self.view.window.rootViewController presentViewController:viewController animated:YES completion:nil];
そして、モーダルView Controllerで、すべてが終了したら、次のように呼び出せます。
[self dismissViewControllerAnimated:YES completion:nil];
この警告の理由は、私がフルサイズのビューではない小さなビューの上にView Controllerを表示していたことです。私のプロジェクトのイメージは以下のとおりです。上記の4つのオプションをクリックしてください。ユーザーは別のchildviewcontrollerのビューに移動します(これはtabViewcontrollerのように機能します)。しかしchildviewcontrollerは小さいサイズのビューを含みます。そのため、childviewcontrollerからのビューを提示すると、この警告が表示されます。
これを避けるために、childviewcontrollerの親のビューを提示することができます。
[self.parentViewController presentViewController:viewController animated:YES completion:nil];
viewDidAppear()
を待ちます。
このエラーは、実際にビューが表示される前にView Controllerを表示しようとした場合にも発生します。たとえば、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];
B.t.w.、これはポップオーバーフォームからテーブルビューセルを表示する場合にも有効です。テーブルビューコントローラが子ビューコントローラとしても追加されていることを確認する必要があります。
問題は、適切なView Controllerの階層がないことです。アプリのrootviewcontrollerを設定してから、新しいView Controllerをプッシュまたは提示することで新しいViewを表示します。各View Controllerにビューを管理させます。 tabbarviewcontrollerのようなコンテナView Controllerだけが、他のView Controllerビューを独自のビューに追加する必要があります。 View Controllerの適切な使用方法については、View Controllerプログラミングガイドを参照してください。 https://developer.Apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS /
私はほとんど同じ問題を抱えています。その理由は、私が別のものの上に "some"コントローラを提示しようとし、そしてアニメーションが完了した後に私がrootとして提示されたコントローラを設定していたということでした。この操作の後に表示される他のすべてのコントローラは、「分離されたView ControllerにView Controllerを表示することは推奨されません」という警告を表示します。そして私はこの警告を解決するために、最初は何も表示せずにrootとして "some"コントローラを設定しています。
削除されました:
[[self rootController] presentViewController:controller animated:YES completion:^{
[self window].rootViewController = controller;
[[self window] makeKeyAndVisible];}];
何も表示せずにrootとして作成してください。
[[self window] setRootViewController:controller];
Swift
これにつまずく人のために、ここにSwiftの答えがあります。
self.parent?.present(viewController, animated: true, completion: nil)
IOS 8では[self.navigationController presentViewController:xxx animated:YES completion:nil]
を使用してください。
このコードを試す
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:<your ViewController object>];
[self.view.window.rootViewController presentViewController:navigationController animated:YES completion:nil];
はい、私は別のビューにあったアラートコントローラを表示している間に同じ警告メッセージに直面しました。後で、私は以下のように親のView ControllerからAlert Controllerを表示することでこれを避けました。
[self.parentViewController presentViewController:alertController animated:YES completion:nil];
新しいView Controllerを親View Controllerの子として表示するView Controllerを追加する必要があります。
あなたがあなたの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
TabBarController
ベースのアプリの場合は、TabBarController
に表示してみてください。
[self.tabBarController presentViewController:viewController animated:YES completion:nil];
理由はself
がTabBarController
の子であり、ChildViewController
から提示しようとしている可能性があります。
最初にルートView Controllerがあることを確認してください。 didFinishLaunchingWithOptions
に設定できます。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window setRootViewController:viewController];
}
この警告の多くの理由私の意見は、ViewControllerから別のものに接続されたセグエがあり、モーダルで表示されるためです。しかし、私が提示しているViewControllerはPageViewControllerによって動的に生成されています。ストーリーボードでそれが切り離されるのはそのためです。私のアプリはそれが原因でクラッシュすることはありません。しかし私はその警告を黙らせたいのです。
カスタムナビゲーションバーがあるこのスレッドに到達し、それを介してAlertViewControllerを呼び出していました。
メインビューコントローラーに子として追加する必要がありました。それから私は何の警告もなしにプレゼントを呼ぶことができました。
Zoomed Image View Controller
をメインViewControllerの子として追加する必要があります。
(例えば)
[self addChildViewController:ZoomedImageViewController];
その後、ZoomedImageViewControllerを呼び出すことができます
[self presentViewController:ZoomedImageViewController];
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)
})
それはあなたがあなたの警告を表示したいのか、種類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];