警告:尝试在视图不在窗口层次结构中显示*on* - swift

Nil*_*ell 77 hierarchy ios presentviewcontroller swift

我试图提出一个数据模型中ViewController 是否有任何已保存的数据.但是我收到以下错误:

警告:尝试显示其视图不在窗口层次结构中的*on*

相关代码:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过使用谷歌找到的不同解决方案但没有成功.

Ace*_*cey 116

此时,在代码中,视图控制器的视图仅已创建,但未添加到任何视图层次结构中.如果你想尽快从那个视图控制器出现,你应该做到viewDidAppear最安全.

  • 如果我把它放在viewDidAppear中,那么当我关闭presentViewController时,它将再次调用viewDidAppear方法并再次呈现viewController.我有一个解决方法,在呈现之前放置一个条件语句,但有没有办法而不是放一个条件陈述? (2认同)
  • 我会说,当屏幕出现时试图呈现另一个模态是奇怪的行为开始,所以状态布尔不是最糟糕的解决方案.同时,考虑一下您需要显示模态的根本原因,看看您是否可以访问该信息. (2认同)
  • 如果你在viewWillAppear中执行此操作,那么在开始演示时,您将处于呈现中间的状态.另一种方法是将它放在viewWillAppear中,但在iOS 8中使用transitionCoordinator属性new来在转换完成时添加代码.更多信息可以在这里找到https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIViewControllerTransitionCoordinator_Protocol/index.html (2认同)

akr*_*ios 34

在目标c:当在mpmovieplayer上呈现viewcontroller时,这解决了我的问题

- (UIViewController*) topMostController
{
    UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;

    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }

    return topController;
}
Run Code Online (Sandbox Code Playgroud)


Jas*_*son 32

斯威夫特3

我有这个不断出现作为一个新手,并发现当前加载模态视图,可以被解雇,但切换到根控制器是最好的,如果你不需要显示模态.

我正在使用它

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc  = storyboard?.instantiateViewController(withIdentifier: "MainAppStoryboard") as! TabbarController
present(vc, animated: false, completion: nil)
Run Code Online (Sandbox Code Playgroud)

使用它来代替我的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
Run Code Online (Sandbox Code Playgroud)

如果您需要在多个故事板屏幕之间切换,只需调整到视图控制器即可.


Edw*_*ard 14

你只需要执行一个延迟选择器 - (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) 
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个黑客(现在可能有效),但会让你在意想不到的情况下崩溃。 (2认同)

Jac*_*vis 14

斯威夫特3.

调用此函数以获取最顶层的视图控制器,然后使该视图控制器存在.

func topMostController() -> UIViewController {
    var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
        while (topController.presentedViewController != nil) {
            topController = topController.presentedViewController!
        }
        return topController
    }
Run Code Online (Sandbox Code Playgroud)

用法:

let topVC = topMostController()
let vcToPresent = self.storyboard!.instantiateViewController(withIdentifier: "YourVCStoryboardID") as! YourViewController
topVC.present(vcToPresent, animated: true, completion: nil)
Run Code Online (Sandbox Code Playgroud)


Vie*_*tiz 11

对于SWIFT

func topMostController() -> UIViewController {
    var topController: UIViewController = UIApplication.sharedApplication().keyWindow!.rootViewController!
    while (topController.presentedViewController != nil) {
        topController = topController.presentedViewController!
    }
    return topController
}
Run Code Online (Sandbox Code Playgroud)


小智 5

斯威夫特4

func topMostController() -> UIViewController {
    var topController: UIViewController = UIApplication.shared.keyWindow!.rootViewController!
    while (topController.presentedViewController != nil) {
        topController = topController.presentedViewController!
    }
    return topController
}
Run Code Online (Sandbox Code Playgroud)


din*_*rma 5

使用主线程来呈现和关闭视图控制器对我有用。

DispatchQueue.main.async { self.present(viewController, animated: true, completion: nil) }
Run Code Online (Sandbox Code Playgroud)