J'ai une application basée sur la barre d'onglets. Il existe des contrôleurs de navigation dans les 5 onglets avec des instances de configuration de contrôleur de vue personnalisé correctement en tant que contrôleurs de vue racine. Cela charge très bien. Deux de ces contrôleurs de vue contiennent des vues de table. Je souhaite montrer un contrôleur de vue modale à l'utilisateur lorsqu'il sélectionne une ligne dans la vue tableau. La (partie pertinente) de la méthode déléguée didSelectRowAtIndexPath se présente comme suit:
SampleSelectorViewController *sampleVC = [[SampleSelectorViewController alloc] init];
[self presentViewController:sampleVC animated:YES completion:NULL];
Le contrôleur de vue modale apparaît MAIS il apparaît après un délai très perceptible. Parfois, l'utilisateur doit même appuyer sur la ligne une seconde fois. Quelques choses que j'ai déjà vérifiées sont:
Des idées/suggestions?
Il semble que l'appel de presentViewController:animated:completion
à partir de tableView:didSelectRowAtIndexPath:
pose problème. Il est également difficile de trouver quelque chose qui se démarque lorsque vous utilisez Time Profiler dans Instruments. Parfois, ma vue modale apparaît en moins d'une seconde et d'autres fois, il faut 4 ou même 9.
Je pense que cela est lié à la variable UIPresentationController
et à la présentation sous-jacentes, ce qui est l'une des rares choses que je vois lorsque je sélectionne la région temporelle entre le moment où vous appuyez sur une ligne et l'affichage de la présentation modale dans Time Profiler.
Il existe un radar décrivant ce problème: http://openradar.appspot.com/19563577
La solution de contournement est simple mais peu satisfaisante: retardez légèrement la présentation pour éviter tout comportement conflictuel à l'origine du ralentissement.
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:nav animated:YES completion:nil];
});
Vous devez l’afficher sous forme modale à partir de votre vc racine (par exemple: customTabBarRootViewController). Enregistrez une référence et utilisez le contrôleur de référence pour l’afficher.
Solution dans Swift 3
Dans le sélecteur d'échantillons ViewController (qui présente le contrôleur de vue), utilisez le code ci-dessous
DispatchQueue.global(qos: .background).async {
// Write your code
}
J'ai également eu ce retard étrange lorsque présenter à partir de tableView:didSelectRowAtIndexPath:
ressemble à un bogue Apple.
Cette solution semble bien fonctionner cependant.
CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Fixes a bug where the main thread may be asleep, especially when using UITableViewCellSelectionStyleNone
Swift 4: Pour Swift 4, vous pouvez utiliser comme suit.
DispatchQueue.main.async {
let popUpVc = Utilities.viewController(name: "TwoBtnPopUpViewController", onStoryboard: "Login") as? TwoBtnPopUpViewController
self.present(popUpVc!, animated: true, completion: nil)
}
Ça marche pour moi.
Si vous appelez present (: animated: completion :) dans tableView (: didSelectRowAt :), selectionStyle == .none pour la cellule sélectionnée tableview et que vous avez ce comportement étrange, essayez ensuite d'appeler tableView.deselectRow (à: animé :) avant toute opération dans tableView (_: didSelectRowAt :).
At-il aidé?
Je suppose que vous définissez également le style de sélection de la cellule sur UITableViewCellSelectionStyleNone
. Je change pour UITableViewCellSelectionStyleDefault
et cela fonctionne parfaitement.
Le problème commun à ce comportement est le suivant:
on définit selectionStyle = .none
pour une cellule de la table (il semble que cela ne dépend pas de la sous-classe UITableViewController
comme elle a été écrite dans http://openradar.appspot.com/19563577 ) et utilise la méthode déléguée
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
animer désélectionner
tableView.deselectRow(at: indexPath, animated: true)
ce qui implique une animation pour une cellule non-animante.
Dans ce cas, la présentation du contrôleur de vue ultérieure est retardée.
Il existe certaines solutions de contournement, y compris dispatch_async
sur le thread principal, mais il est préférable de ne pas appeler deselectRow
même sans animation sur les cellules non sélectionnables de votre code.