ViewController
を提示しようとしていますifデータモデルに保存されたデータがあります。しかし、次のエラーが表示されます。
警告:*ビューがウィンドウ階層にない*に*を表示しようとしています
関連コード:
override func viewDidLoad() {
super.viewDidLoad()
loginButton.backgroundColor = UIColor.orangeColor()
var request = NSFetchRequest(entityName: "UserData")
request.returnsObjectsAsFaults = false
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var results:NSArray = context.executeFetchRequest(request, error: nil)!
if(results.count <= 0){
print("Inga resultat")
} else {
print("SWITCH VIEW PLOX")
let internVC = self.storyboard?.instantiateViewControllerWithIdentifier("internVC") as internViewController
self.presentViewController(internVC, animated: true, completion: nil)
}
}
Googleを使用して見つかったさまざまなソリューションを試してみましたが成功しませんでした。
コードのこの時点では、View Controllerのビューは作成されているだけで、ビュー階層には追加されていません。できるだけ早くそのView Controllerから表示したい場合は、viewDidAppear
で最も安全にする必要があります。
目的C:mpmovieplayerの上にViewControllerを表示するときの問題を解決しました
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
スイフト3
私はこれを初心者として続けており、現在のロードモーダルビューは閉じることができますが、モーダルを表示する必要がない場合はルートコントローラーに切り替えるのが最適です。
私はこれを使用していました
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard?.instantiateViewController(withIdentifier: "MainAppStoryboard") as! TabbarController
present(vc, animated: false, completion: nil)
私のtabControllerでこれを代わりに使用:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let view = storyboard.instantiateViewController(withIdentifier: "MainAppStoryboard") as UIViewController
let appDelegate = UIApplication.shared.delegate as! AppDelegate
//show window
appDelegate.window?.rootViewController = view
複数のストーリーボード画面を切り替える必要がある場合は、View Controllerに合わせて調整してください。
スウィフト3。
この関数を呼び出して、最上位のView Controllerを取得し、そのView Controllerを存在させます。
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
使用法:
let topVC = topMostController()
let vcToPresent = self.storyboard!.instantiateViewController(withIdentifier: "YourVCStoryboardID") as! YourViewController
topVC.present(vcToPresent, animated: true, completion: nil)
セレクターを遅延して実行する必要があります-(0秒が機能します)。
override func viewDidLoad() {
super.viewDidLoad()
perform(#selector(presentExampleController), with: nil, afterDelay: 0)
}
@objc private func presentExampleController() {
let exampleStoryboard = UIStoryboard(named: "example", bundle: nil)
let exampleVC = storyboard.instantiateViewController(withIdentifier: "ExampleVC") as! ExampleVC
present(exampleVC, animated: true)
}
スイフト用
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
スイフト4
func topMostController() -> UIViewController {
var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
while (topController.presentedViewController != nil) {
topController = topController.presentedViewController!
}
return topController
}
ユーザーがディープリンクを開いた後、コントローラーを表示しているときにこのエラーが発生しました。私はこれが最善の解決策ではないことを知っていますが、あなたが短い時間枠にいるなら、ここに簡単な修正があります-コードをasyncAfter
でラップするだけです:
DispatchQueue.main.asyncAfter(deadline: .now() + 0.7, execute: { [weak self] in
navigationController.present(signInCoordinator.baseController, animated: animated, completion: completion)
})
提示するコントローラーがviewDidAppear
を呼び出す時間を与えます。
Swift 3.0以降の場合
public static func getTopViewController() -> UIViewController?{
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
return topController
}
return nil}
私は非常に多くのアプローチを試みました!唯一の有用なことは:
if var topController = UIApplication.shared.keyWindow?.rootViewController
{
while (topController.presentedViewController != nil)
{
topController = topController.presentedViewController!
}
}
let storyboard = UIStoryboard(name: "test", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "teststoryboard") as UIViewController
UIApplication.shared.keyWindow?.rootViewController?.present(vc, animated: true, completion: nil)
これは、最上位のビューであることを確認するために機能するように見えました。
エラーが発生しました
警告:myapp.testControllerで0x7fdd01703990を表示しようとしています:myapp.testController:0x7fdd01703690のビューはウィンドウ階層にありません!
これがSwift 3で他の人を助けることを願っています
ここでのtopViewControllerのすべての実装は、UINavigationController
またはUITabBarController
がある場合を完全にサポートするわけではありません。これら2つの場合、少し異なる処理が必要です。
UITabBarController
およびUINavigationController
には、別の実装が必要です。
TopMostViewControllerを取得するために使用しているコードは次のとおりです。
protocol TopUIViewController {
func topUIViewController() -> UIViewController?
}
extension UIWindow : TopUIViewController {
func topUIViewController() -> UIViewController? {
if let rootViewController = self.rootViewController {
return self.recursiveTopUIViewController(from: rootViewController)
}
return nil
}
private func recursiveTopUIViewController(from: UIViewController?) -> UIViewController? {
if let topVC = from?.topUIViewController() { return recursiveTopUIViewController(from: topVC) ?? from }
return from
}
}
extension UIViewController : TopUIViewController {
@objc open func topUIViewController() -> UIViewController? {
return self.presentedViewController
}
}
extension UINavigationController {
override open func topUIViewController() -> UIViewController? {
return self.visibleViewController
}
}
extension UITabBarController {
override open func topUIViewController() -> UIViewController? {
return self.selectedViewController ?? presentedViewController
}
}
トップビューコントローラーを見つけるのではなく、使用することができます
viewController.modalPresentationStyle = UIModalPresentationStyle.currentContext
ViewControllerは表示するコントローラーです。これは、TabBar、NavBarなどの階層にさまざまな種類のビューがある場合に便利です。
他の表示スタイルは Apple doc にあります
これまでの回答は、ビューを表示するView Controllerが1)View階層にまだ追加されていない、または2)Top View Controllerではない状況に関連しています。
別の可能性は、別のアラートがすでに表示されているときにアラートを表示する必要があり、まだ却下されていないことです。