web-dev-qa-db-fra.com

Retard dans la présentation d'un contrôleur de vue modale

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:

  • La méthode didSelectRowAtIndexPath de la vue Table est appelée lorsque l'utilisateur appuie sur la ligne.
  • La méthode didSelectRowAtIndexPath ne contient aucun appel bloquant. Aucune opération de réseau n'est effectuée et la configuration du contrôleur de vue modale n'implique aucune tâche de traitement intensif. Les données affichées sont statiques.
  • Si je place le nouveau contrôleur de vue sur la pile de navigation (tout le reste restant exactement identique), il se comporte parfaitement sans délai. Ce n'est que lorsqu'il est présenté de manière modale que le retard est rencontré.

Des idées/suggestions?

30
Numan Tariq

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];
});
49
azsromej

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.

3
Gilad

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

}
2

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
2
trapper

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.

2
Arshad Shaik

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é?

2
Artem Kirillov

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.

2
Neeeeeil

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. 

0
malex