performSegueWithIdentifier très lent lorsque la séquence est modale
j'ai une vue de table simple où je gère l'action select sur la vue de table. Cette action suit une séquence.
si la séquence est une push
, la vue suivante s'affiche immédiatement.
Si la séquence est une modal
, la vue suivante peut être:
- prend 6 secondes ou plus pour afficher
- montre immédiatement si je tape à nouveau (deuxième tape)
j'ai essayé de regarder autour pour quelques idées, mais aucun ne semble applicable à ma situation. En particulier:
- je suis exécution de la séquence sur l'INTERFACE principale du fil
- mon point de vue est très simple (il n'y a donc pas de problème dans
viewDidLoad
). De Plus, le fait qu'elle apparaisse presque instantanée lorsque la séquence estpush
indique qu'il n'y a aucun problème pour charger la vue cible - j'ai essayé de passer
nil
ausender
; même effet.
Quelqu'un a-t-il une idée à ce sujet?
7 réponses
faites-moi confiance et essayez ceci. J'ai rencontré ce problème à plusieurs reprises.
Dans Swift 2:
dispatch_async(dispatch_get_main_queue(),{
self.performSegue(withIdentifier:mysegueIdentifier,sender: self)
})
ou pour Swift 3:
DispatchQueue.main.async {
self.performSegue(withIdentifier: mysegueIdentifier,sender: self)
}
il me semble (...) que ce problème ne se produit que lorsque la cellule selectionType
n'est pas .none
.
vous pouvez le changer à n'importe quelle autre option (au storyboard Attribute inspector
, mettez le champ Selection
) et il fonctionnera très bien (travailler pour moi...).
Le contre, c'est qu'il salisse la cellule de l'INTERFACE utilisateur.
vous pouvez appeler la suite dans DispatchQueue.main.async{}
bloc à la didSelect
fonction de délégué de UITableViewDelegate
comme les gens mentionnent avant.
j'ai utilisé la première solution et ajouté à la cellule elle-même -
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(false, animated: false)
}
cela va faire la cellule 'highlight' au robinet, mais il va revenir à son UI habituelle immédiatement et il va bien pour moi...
il semble y avoir plusieurs situations où l'exécution d'une séquence ne fonctionnera pas correctement. Par exemple, si vous appelez performSegue
du gestionnaire d'action d'une séquence de décompression, vous rencontrerez divers problèmes, même si vous êtes sur le fil principal. Sur mon projet actuel, j'appelle performSegue
de la méthode didSelectRowAt
d'une vue de table. C'est l'une des étapes les plus basiques et bien sûr je suis sur le fil principal, mais je voyais les symptômes exacts que l'opération décrit.
Je ne sais pas pourquoi cela se produit dans certains cas et pas dans d'autres, mais j'ai constaté que le fait de reporter l'appel performSegue
en utilisant async
règle tout problème potentiel. Cela ressemblait à un piratage et me rendait nerveux, mais à ce point j'ai plusieurs projets mûrs utilisant cette approche et il semble maintenant comme la "bonne" façon de faire une séquence manuelle.
Voici la version Swift 3 du code (voir les autres posts pour les versions Swift 2 et Obj-C)):
DispatchQueue.main.async {
self.performSegue(withIdentifier: "theIdentifier", sender: theSender)
}
la solution acceptée a fonctionné pour moi. Code mis à jour pour Swift 2.0 ci-dessous:
dispatch_async(dispatch_get_main_queue(),{
self.performSegueWithIdentifier(mysegueIdentifier, sender:self)
})
l'Espoir d'aider ce yo peut créer par programmation modal de transition de ce genre dans Swift:
let myStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let modalViewController = myStoryboard.instantiateViewControllerWithIdentifier("myModalViewController") as! myModalViewController
modalViewController.modalTransitionStyle = UIModalTransitionStyle.CoverVertical
let navController = UINavigationController(rootViewController: accountManager)
dispatch_async(dispatch_get_main_queue(),{
self.presentViewController(navController, animated: true, completion: nil)
})
pour les développeurs organisant leur code à travers le sous-codage, j'ai trouvé une solution assez simple que je voudrais partager (Swift 4):
import UIKit
class ABCViewController: UIViewController {
// ... Other useful methods like overriding deinit and didReceiveMemoryWarning
// Performs a segue on the main thread to ensure it will
// transition once a UI-slot is available
func performSegueOnMainThread(with identifier: String, sender: Any?) {
DispatchQueue.main.async {
self.performSegue(with: identifier, sender: sender)
}
}
}
alors, appelez-le simplement de votre implémentation:
myViewController.performSegueOnMainThread(with: "ShowDetailsSegue", sender: self)
j'ai essayé de fixer ce plusieurs façons dont y compris le déplacement vers le fil principal ci-dessus. Cela a fonctionné pour moi:
dans storyboard, sélectionnez la vue de la table en question, (sélectionnez-la dans le plan du document pour vous assurer que vous avez la bonne chose. Puis, dans attributes inspector, vous pourrez voir les attributs pour la vue de la table ainsi que le scrollview contenant en dessous (toutes les vues de la table sont basées sur scroll view). Il y a cette stupide petite boîte qui s'appelle "retards" contenu touche". Décochez la case. Il y a aussi un "permet des touches annulables" que j'imagine que vous voulez s'assurer est non vérifié aussi, car je pense que double touches ont été gâcher la mienne.