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)
})
}
J'ai trouvé une solution.
J'ai ajouter le code suivant dans HomeViewController.viewDidLoad
et ça marche!
definesPresentationContext = true
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
.
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()
}
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.
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.
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)
}
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)
}