Exemple reproductible minimal (Xcode 11.2 beta, cela fonctionne dans Xcode 11.1):
struct Parent: View {
var body: some View {
NavigationView {
Text("Hello World")
.navigationBarItems(
trailing: NavigationLink(destination: Child(), label: { Text("Next") })
)
}
}
}
struct Child: View {
@Environment(\.presentationMode) var presentation
var body: some View {
Text("Hello, World!")
.navigationBarItems(
leading: Button(
action: {
self.presentation.wrappedValue.dismiss()
},
label: { Text("Back") }
)
)
}
}
struct ContentView: View {
var body: some View {
Parent()
}
}
Le problème semble résider dans le fait de placer mon NavigationLink
intérieur d'un navigationBarItems
modificateur imbriqué dans une vue SwiftUI dont la vue racine est a NavigationView
. Le rapport d'erreur indique que j'essaie d'accéder à un contrôleur de vue qui n'existe pas lorsque je navigue vers Child
puis vers Parent
.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'
*** First throw call stack:
Si je devais plutôt placer cela NavigationLink
dans le corps de la vue comme ci-dessous, cela fonctionne très bien.
struct Parent: View {
var body: some View {
NavigationView {
NavigationLink(destination: Child(), label: { Text("Next") })
}
}
}
S'agit-il d'un bogue SwiftUI ou d'un comportement attendu?
EDIT: J'ai ouvert un problème avec Apple dans leur assistant de rétroaction avec l'ID FB7423964
au cas où quelqu'un d'Apple se soucierait de peser :).
EDIT: Mon ticket ouvert dans l'assistant de commentaires indique qu'il y a plus de 10 problèmes similaires signalés. Ils ont mis à jour la résolution avec Resolution: Potential fix identified - For a future OS update
. Les doigts croisés que le correctif atterrit bientôt.
EDIT: Cela a été corrigé dans iOS 13.3!
ContentView.swift
. Je vais modifier le message, mais le plantage ne se produit que lorsque vous naviguez vers l'avant puis vers l'arrière.Réponses:
C'était assez douloureux pour moi! Je l'ai laissé jusqu'à ce que la plupart de mon application soit terminée et que j'ai eu l'espace mental pour faire face au crash.
Je pense que nous pouvons tous convenir qu'il y a des choses assez géniales avec SwifUI mais que le débogage peut être difficile.
À mon avis, je dirais que c'est un BUG. Voici ma justification:
Si vous encapsulez l'appel de présentationModeMode dans un délai asynchrone d'environ une demi-seconde, vous devriez constater que le programme ne se bloquera plus.
Cela me suggère que le bogue est un comportement inattendu en profondeur dans la façon dont SwiftUI s'interface avec tous les autres codes UIKit pour gérer les différentes vues. En fonction de votre code réel, vous constaterez peut-être qu'en cas de complexité mineure dans la vue, le crash ne se produira pas. Par exemple, si vous passez d'une vue à une qui a une liste et que cette liste est vide, vous obtiendrez un plantage sans le délai asynchrone. D'un autre côté, si vous n'avez qu'une seule entrée dans cette vue de liste, forçant une itération de boucle à générer la vue parent, vous verrez que le crash ne se produira pas.
Je ne suis pas sûr de la robustesse de ma solution d'envelopper l'appel de rejet dans un délai. Je dois le tester beaucoup plus. Si vous avez des idées à ce sujet, faites-le moi savoir! Je serais très heureux d'apprendre de vous!
la source
.navigationBarItems()
points pour que ce soit un bug.Cela m'a également frustré pendant un certain temps. Au cours des derniers mois, en fonction de la version Xcode, de la version du simulateur et du type et / ou de la version réelle de l'appareil, il est passé de fonctionner à ne pas fonctionner à nouveau, apparemment au hasard. Cependant, récemment, cela a échoué de façon constante pour moi, alors hier, j'ai plongé profondément. J'utilise actuellement Xcode version 11.2.1 (11B500).
Il semble que le problème tourne autour de la barre de navigation et de la façon dont les boutons y ont été ajoutés. Donc, au lieu d'utiliser un NavigationLink () pour le bouton lui-même, j'ai essayé d'utiliser un Button () standard avec une action qui définit une variable @State qui active un NavigationLink caché. Voici un remplacement pour Robert's Parent View:
Pour moi, cela fonctionne de manière très cohérente sur tous les simulateurs et tous les appareils réels.
Voici mes vues d'aide:
Voici un exemple d'utilisation:
la source
Il s'agit d'un bug majeur et je ne vois pas de bonne façon de le contourner. A bien fonctionné dans iOS 13 / 13.1 mais 13.2 se bloque.
Vous pouvez réellement le répliquer d'une manière beaucoup plus simple (ce code est littéralement tout ce dont vous avez besoin).
J'espère qu'Apple le triera car il cassera sûrement des tas d'applications SwiftUI (y compris la mienne).
la source
Comme solution de contournement, basé sur la réponse de Chuck H ci-dessus, j'ai encapsulé le NavigationLink comme un élément caché:
Ensuite, vous pouvez l'utiliser dans un NavigationView (ce qui est crucial) et le déclencher à partir d'un bouton dans une barre de navigation:
Enveloppez-le dans les commentaires "// HACK" donc quand Apple corrige cela, vous pouvez le remplacer.
la source
Sur la base des informations que vous avez fournies et spécialement d'un commentaire que @Robert a fait à propos de l'emplacement de NavigationView, j'ai trouvé un moyen de contourner le problème au moins dans mon scénario spécifique.
Dans mon cas, j'avais un TabView qui était enfermé dans un NavigationView comme ceci:
Ce code se bloque car tout le monde signale dans iOS 13.2 et fonctionne dans iOS 13.1. Après quelques recherches, j'ai trouvé une solution à cette situation.
Fondamentalement, je déplace la NavigationView sur chaque écran séparément sur chaque onglet comme ceci:
Cela va à l'encontre de la prémisse de simplicité de SwiftUI, mais cela fonctionne sur iOS 13.2.
la source
Xcode 11.2.1 Swift 5
JE L'AI! Il m'a fallu quelques jours pour comprendre celui-ci ...
Dans mon cas, lorsque j'utilise SwiftUI, j'obtiens un plantage uniquement si le bas de ma liste s'étend au-delà de l'écran, puis j'essaie de «déplacer» les éléments de la liste. Ce que j'ai fini par découvrir, c'est que si j'ai trop de "trucs" sous List (), alors il se bloque en déplacement. Par exemple, sous ma List (), j'avais un bouton Text (), Spacer (), Button (), Spacer () (). Si je commentais l'un de ces objets, je ne pouvais pas recréer le crash. Je ne sais pas quelles sont les limitations, mais si vous obtenez ce plantage, essayez de supprimer des objets sous votre liste pour voir si cela aide.
la source
Bien que je ne puisse voir aucun plantage, votre code a quelques problèmes:
en définissant l'élément de tête, vous tuez réellement le comportement par défaut des transitions de navigation. (essayez de glisser du côté avant pour voir si cela fonctionne).
Donc pas besoin d'avoir un bouton là-bas. Laissez-le tel quel et vous avez un bouton de retour gratuit.
Et n'oubliez pas selon HIG , le titre du bouton de retour devrait montrer où il va, pas ce que c'est! Essayez donc de définir un titre pour la première page pour l'afficher sur l'un des boutons de retour qui y apparaît.
la source
FWIW - Les solutions ci-dessus suggérant un Hack NavigationLink caché sont toujours la meilleure solution de contournement dans iOS 13.3b3. J'ai également déposé un FB7386339 pour la postérité, et j'ai été fermé de la même manière que les autres FB susmentionnés: "Correction potentielle identifiée - Pour une future mise à jour du système d'exploitation".
Doigts croisés.
la source
Il est résolu dans iOS 13.3. Mettez simplement à jour votre système d'exploitation et votre xCode.
la source
.buttonStyle(PlainButtonStyle())
modificateur NavigationLink et réessayez. faites-moi savoir si vous avez posé une question.