ios Tentativo di presentare UIViewController su UIViewController la cui vista non è nella gerarchia delle finestre





13 Answers

Un'altra potenziale causa:

Ho riscontrato questo problema quando per sbaglio ho presentato due volte lo stesso controller di visualizzazione. (Una volta con performSegueWithIdentifer:sender: che è stato chiamato quando il pulsante è stato premuto, e una seconda volta con un seguito collegato direttamente al pulsante).

In effetti, due sequenze sparavano contemporaneamente, e ho ricevuto l'errore: Attempt to present X on Y whose view is not in the window hierarchy!

ios cocoa-touch ios6 views hierarchy

Ho appena iniziato ad usare Xcode 4.5 e ho ricevuto questo errore nella console:

Avvertenza: tentare di presentare <finishViewController: 0x1e56e0a0> su <ViewController: 0x1ec3e000> la cui vista non è nella gerarchia della finestra!

La vista è ancora in fase di presentazione e tutto nell'app funziona perfettamente. È qualcosa di nuovo in iOS 6?

Questo è il codice che sto usando per cambiare tra le visualizzazioni:

UIStoryboard *storyboard = self.storyboard;
finishViewController *finished = 
[storyboard instantiateViewControllerWithIdentifier:@"finishViewController"];

[self presentViewController:finished animated:NO completion:NULL];



Per visualizzare qualsiasi sottoview alla vista principale, utilizzare il seguente codice

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

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

[yourCurrentViewController presentViewController:composeViewController animated:YES completion:nil];

Per Ignora qualsiasi sottoview dalla vista principale, usa il seguente codice

UIViewController *yourCurrentViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

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

[yourCurrentViewController dismissViewControllerAnimated:YES completion:nil];



Probabilmente, come me, hai una vista di root viewController

Voglio visualizzare un ViewController in un contesto non-UIViewController ,

Quindi non posso usare questo codice:

[self presentViewController:]

Quindi, ottengo un UIViewController:

[[[[UIApplication sharedApplication] delegate] window] rootViewController]

Per qualche ragione (bug logico), rootViewController è qualcosa di diverso dal previsto (un normale UIViewController ). Quindi correggo il bug, sostituendo rootViewController con un UINavigationController , e il problema è scomparso.




Il mio problema era che stavo eseguendo il seguito nel metodo di didFinishLaunchingWithOptions prima di chiamare makeKeyAndVisible() sulla finestra.




Se hai un oggetto AVPlayer con un video riprodotto, devi prima mettere in pausa il video.




Funziona bene, prova questo. Link

UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;
[top presentViewController:secondView animated:YES completion: nil];



Ho avuto lo stesso problema. Ho dovuto incorporare un controller di navigazione e presentare il controller attraverso di esso. Di seguito è riportato il codice di esempio.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    UIImagePickerController *cameraView = [[UIImagePickerController alloc]init];
    [cameraView setSourceType:UIImagePickerControllerSourceTypeCamera];
    [cameraView setShowsCameraControls:NO];

    UIView *cameraOverlay = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 768, 1024)];
    UIImageView *imageView = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"someImage"]];
    [imageView setFrame:CGRectMake(0, 0, 768, 1024)];
    [cameraOverlay addSubview:imageView];

    [cameraView setCameraOverlayView:imageView];

    [self.navigationController presentViewController:cameraView animated:NO completion:nil];
//    [self presentViewController:cameraView animated:NO completion:nil]; //this will cause view is not in the window hierarchy error

}



Devo scrivere sotto la linea.

self.searchController.definesPresentationContext = true

invece di

self.definesPresentationContext = true

in UIViewController




Ho riscontrato questo problema e la causa principale era la sottoscrizione a un gestore di clic del pulsante (TouchUpInside) più volte.

Si stava iscrivendo a ViewWillAppear, che veniva chiamato più volte da quando avevamo aggiunto la navigazione per passare a un altro controller, e poi tornarci.




Mi è successo che il seguito nello storyboard fosse una specie di rottura . Eliminando il seguito (e creando di nuovo lo stesso seguito) risolto il problema.




Ho appena avuto questo problema, ma non aveva niente a che fare con i tempi. Stavo usando un singleton per gestire le scene e l'ho impostato come presentatore. In altre parole, il "Sé" non era collegato a nulla. Ho appena fatto la sua "scena" interiore il nuovo presentatore e voilà, ha funzionato. (Voila perde il suo tocco dopo aver appreso il suo significato, heh).

Quindi sì, non si tratta di "trovare magicamente la strada giusta", si tratta di capire dove si trova il tuo codice e cosa sta facendo. Sono felice che Apple abbia dato un messaggio di avvertimento semplice in inglese, anche con emozione. Complimenti al dev della mela che l'ha fatto !!




Purtroppo, la soluzione accettata non ha funzionato per il mio caso. Stavo cercando di passare a un nuovo controller di visualizzazione subito dopo il distacco da un altro controller di visualizzazione.

Ho trovato una soluzione utilizzando un flag per indicare quale percorso di svolgimento è stato chiamato.

@IBAction func unwindFromAuthenticationWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToMainTabBar = true
}

@IBAction func unwindFromForgetPasswordWithSegue(segue: UIStoryboardSegue) {
    self.shouldSegueToLogin = true
}

Quindi presentare il VC desiderato con present(_ viewControllerToPresent: UIViewController)

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    if self.shouldSegueToMainTabBar {
        let mainTabBarController = storyboard.instantiateViewController(withIdentifier: "mainTabBarVC") as! MainTabBarController
        self.present(mainTabBarController, animated: true)
        self.shouldSegueToMainTabBar = false
    }
    if self.shouldSegueToLogin {
        let loginController = storyboard.instantiateViewController(withIdentifier: "loginVC") as! LogInViewController
        self.present(loginController, animated: true)
        self.shouldSegueToLogin = false
    }
}

Fondamentalmente, il codice di cui sopra mi consentirà di cogliere la pausa dal login / registrazione VC e navigare verso la dashboard, o prendere l'azione di svolgimento da dimenticare la password VC e navigare fino alla pagina di accesso.




Nella mia situazione, non ero in grado di mettere il mio in un override di classe. Quindi, ecco cosa ho ottenuto:

let viewController = self // I had viewController passed in as a function,
                          // but otherwise you can do this


// Present the view controller
let currentViewController = UIApplication.shared.keyWindow?.rootViewController
currentViewController?.dismiss(animated: true, completion: nil)

if viewController.presentedViewController == nil {
    currentViewController?.present(alert, animated: true, completion: nil)
} else {
    viewController.present(alert, animated: true, completion: nil)
}





Related