2015-09-21 13 views
24

Questa è la mia prima applicazione per iOS.Avvertenza: Tentativo di presentare * su * che è già presente (null)

Così ho un UIVIewController con un UITableView dove ho integrato un UISearchBar e un UISearchController al fine di filtrare TableCells per visualizzare

override func viewDidLoad() { 
    menuBar.delegate = self 
    table.dataSource = self 
    table.delegate = self 
    let nib = UINib(nibName: "ItemCellTableViewCell", bundle: nil) 
    table.registerNib(nib, forCellReuseIdentifier: "Cell") 

    let searchButton = UIBarButtonItem(barButtonSystemItem: .Search, target: self, action: "search:") 
    menuBar.topItem?.leftBarButtonItem = searchButton 
    self.resultSearchController = ({ 
     let controller = UISearchController(searchResultsController: nil) 
     controller.searchResultsUpdater = self 
     controller.dimsBackgroundDuringPresentation = false 
     return controller 
    })() 
    self.table.reloadData() 
} 

sto usando anche un segue modale al fine di aprire il ViewController cui elemento Mostrerò i dettagli dell'elemento.

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    self.index = indexPath.row 
    self.performSegueWithIdentifier("ItemDetailFromHome", sender: self) 
} 

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { 
    if (segue.identifier == "ItemDetailFromHome") { 
     let settingsVC = segue.destinationViewController as! ItemDetailViewController 
     settingsVC.parent = self 
     if self.isSearching == true && self.searchText != nil && self.searchText != "" { 
      settingsVC.item = self.filteredItems[self.index!] 
     } else { 
      settingsVC.item = self.items[self.index!] 
     } 

    } 
} 

Questo funziona bene fino a quando cerco di visualizzare il ItemDetailViewController per un elemento filtrato (attraverso il UISearchController).

ho il seguente messaggio:

Warning: Attempt to present <ItemDetailViewController: *> on <HomeViewController: *> which is already presenting (null) 

Ad ogni volta che mi accingo alla funzione ItemDetailViewController.viewDidLoad() ma dopo che, quando la ricerca viene attivato ho l'errore precedente.

Qualche idea? Ho provato a utilizzare il seguente invio asincrono ma senza successo

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 
    self.index = indexPath.row 
    dispatch_async(dispatch_get_main_queue(), {() -> Void in 
     self.performSegueWithIdentifier("ItemDetailFromHome", sender: self) 
    }) 
} 
+0

se si sta impostando ItemDetailFromHome dal controller Tableview non c'è bisogno di chiamare self.performSegueWithIdentifier (" ItemDetailFromHome ", sender: self) in ha selezionato la riga al percorso dell'indice – Johnykutty

+0

Infatti," ItemDetailViewController' sarà una vista utilizzata da diversi follow/viewController (mutualizzati). – Splendf

+0

Grande, e come posso farlo? in cellForRowAtIndexPath? Ho appena visto esempi con performSegue – Splendf

risposta

42

Ho trovato una soluzione.

Ho aggiunto il seguente codice in HomeViewController.viewDidLoad e questo funziona!

definesPresentationContext = true 
+0

Questo ha funzionato anche per me. Grazie! –

+33

Puoi spiegare perché questo risolve il problema? – Shahar

+0

salva il mio amico di vita! – PeiweiChen

1

Ho affrontato lo stesso tipo di problema Quello che ho fatto è da Interface Builder selezionati Miei segue Il suo genere è "Presente modale" e la sua presentazione è stata "Over contesto attuale"

ho cambiato il presentazione a "Default", e poi ha funzionato per me.

15

Nel mio caso, ho trovato il mio codice per presentare il nuovo viewController (uno UIAlertController) chiamato due volte.

Controllare prima di scherzare con definesPresentationContext.

+0

Grazie, funziona. – Leo

+2

Sembra quasi sciocco, ma scommetto nella stragrande maggioranza dei casi questa sarà la risposta corretta. Certo, ho trovato una seconda chiamata ... –

+0

Sì, in alcuni casi dobbiamo controllare 'presentatoViewController' prima di presentare – onmyway133

0

Questo è successo con me sul nostro progetto. Stavo presentando il nostro log in/logout ViewController come pop-over. Ma ogni volta che ho provato ad accedere di nuovo fuori e visualizzare il pop-di nuovo, mi è stato sempre questo disconnesso nella mia console:

Warning: Attempt to present UIViewController on <MY_HOME_VIEW_CONTROLLER> which is already presenting (null)

La mia ipotesi è che il pop-over è ancora detenuto dalla mia ViewController anche se non era visibile.

Tuttavia si sta tentando di visualizzare il nuovo ViewController, il seguente codice che ho usato per risolvere il problema dovrebbe funzionare per voi:

func showLoginForm() { 

    // Dismiss the Old 
    if let presented = self.presentedViewController { 
     presented.removeFromParentViewController() 
    } 

    // Present the New 
    let storyboard = UIStoryboard(name: "MPTLogin", bundle: Bundle(for: MPTLogin.self)) 
    let loginVC = storyboard.instantiateViewController(withIdentifier: "LogInViewController") as? MPTLogInViewController 
    let loginNav = MPTLoginNav(rootViewController: loginVC!) 
    loginNav.modalPresentationStyle = .pageSheet; 
    self.present(loginNav, animated: true, completion: nil) 
} 
0

Nel mio caso stavo cercando di presentare un UIAlertController ad un certo punto nel durata della app dopo l'utilizzo di uno nello stesso UINavigationController.

Non stavo usando il UISearchController correttamente e ho dimenticato di impostare searchController.isActive = false prima di chiudere. Più tardi nell'app ho provato a presentare l'avviso ma il controller di ricerca, anche se non visibile al momento, stava ancora controllando il contesto della presentazione.

0

Questo è ciò che alla fine ha funzionato per me, in quanto il mio progetto non aveva esattamente un NavigationVC ma invece, singoli VC distaccati. come file XI ter

Questo codice ha prodotto il bug:

present(alertVC, animated: true, completion: nil) 

Questo codice corretto il bug:

if presentedViewController == nil{ 
     navigationController?.present(alertVC, animated: true, completion: nil) 
    }