web-dev-qa-db-fra.com

Attention: Tentative de présenter * sur * ce qui est déjà présent

Ceci est ma première application pour iOS.

J'ai donc une UIVIewController avec une UITableView où j'ai intégré une UISearchBar et une UISearchController afin de filtrer les cellules de tableau pour afficher

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()
}

J'utilise également une séquence modale afin d'ouvrir la variable ViewController de l'élément où je vais afficher les détails de l'élément.

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!]
        }

    }
}

Cela fonctionne bien jusqu'à ce que j'essaie d'afficher la ItemDetailViewController pour un élément filtré (via la UISearchController).

J'ai le message suivant:

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

A chaque fois que je vais à la fonction ItemDetailViewController.viewDidLoad(), mais après que lorsque la recherche est activée, j'ai l'erreur précédente.

Une idée ? J'ai essayé d'utiliser la répartition asynchrone suivante mais sans succès

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

J'ai trouvé une solution.

J'ai ajouter le code suivant dans HomeViewController.viewDidLoad et ça marche!

definesPresentationContext = true
57
Splendf

Dans mon cas, j'ai trouvé mon code pour présenter le nouveau viewController (un UIAlertController) appelé deux fois.

Vérifiez ceci avant de jouer avec definesPresentationContext.

21
grahamparks

Dans mon cas, j'ai essayé trop tôt de montrer le nouveau UIViewController avant de fermer le précédent. Le problème a été résolu par un appel avec un léger retard:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
     self.callMethod()
}
5
Pavel Kataykin

Dans mon cas, j'essayais de présenter une UIAlertController à un moment donné dans la vie de l'application après avoir utilisé une UISearchController dans la même UINavigationController

Je n'utilisais pas correctement la UISearchController et j'ai oublié de définir searchController.isActive = false avant de le quitter. Plus tard dans l'application, j'ai essayé de présenter l'alerte, mais le contrôleur de recherche, bien que non visible à l'époque, contrôlait toujours le contexte de la présentation.

2
Clay Ellis

J'ai rencontré le même type de problème Ce que j'ai fait, c'est Interface Builder qui a sélectionné mon segment Son genre était "Present Modally"

j'ai changé la présentation en "Défaut", puis cela a fonctionné pour moi.

2
Prasanna Kumar

Pour moi, c’était une alerte qui interférait avec le nouveau VC que j’étais sur le point de présenter.

J'ai donc déplacé le nouveau code de présent VC dans la partie OK de mon alerte, comme ceci:

    func showSuccessfullSignupAndGoToMainView(){

    let alert = UIAlertController(title: "Alert", message: "Sign up was successfull.", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
        switch action.style{
        case .default:
            // Goto Main Page to show businesses
            let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
            let vc : MainViewController = mainStoryboard.instantiateViewController(withIdentifier: "MainViewController") as! MainViewController
            self.present(vc, animated: false, completion: nil)

        case .cancel:
            print("cancel")

        case .destructive:
            print("destructive")

        }}))
    self.present(alert, animated: true, completion: nil)
}
0
Zich

C'est ce qui a finalement fonctionné pour moi, car mon projet ne comportait pas exactement un système de NavigationVC, mais des VC individuels isolés. en tant que fichiers xib

Ce code a généré le bogue:

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

Ce code a corrigé le bug:

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