Minimal reproduzierbares Beispiel (Xcode 11.2 Beta, dies funktioniert in 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()
}
}
Das Problem scheint darin zu liegen, dass ich mich NavigationLink
in einem navigationBarItems
Modifikator befinde, der in einer SwiftUI-Ansicht verschachtelt ist, deren Stammansicht a ist NavigationView
. Der Absturzbericht zeigt an, dass ich versuche, zu einem Ansichts-Controller zu wechseln, der nicht vorhanden ist, wenn ich vorwärts zu Child
und dann zurück zu navigiere Parent
.
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Tried to pop to a view controller that doesn't exist.'
*** First throw call stack:
Wenn ich das stattdessen NavigationLink
wie unten im Hauptteil der Ansicht platzieren würde, funktioniert es einwandfrei.
struct Parent: View {
var body: some View {
NavigationView {
NavigationLink(destination: Child(), label: { Text("Next") })
}
}
}
Ist dies ein SwiftUI-Fehler oder ein erwartetes Verhalten?
BEARBEITEN: Ich habe ein Problem mit Apple in seinem Feedback-Assistenten mit der ID eröffnet, FB7423964
falls jemand von Apple da draußen abwägen möchte :).
BEARBEITEN: Mein offenes Ticket im Feedback-Assistenten zeigt an, dass mehr als 10 ähnliche Probleme gemeldet wurden. Sie haben die Auflösung mit aktualisiert Resolution: Potential fix identified - For a future OS update
. Daumen drücken, dass der Fix bald landet.
EDIT: Dies wurde in iOS 13.3 behoben!
ContentView.swift
. Ich werde den Beitrag bearbeiten, aber der Absturz tritt nur auf, wenn Sie vorwärts und dann zurück navigieren.Antworten:
Das war ein ziemlicher Schmerzpunkt für mich! Ich habe es verlassen, bis der größte Teil meiner App fertig war und ich den Verstand hatte, um mit dem Absturz fertig zu werden.
Ich denke, wir können uns alle einig sein, dass SwifUI einige großartige Dinge enthält, aber dass das Debuggen schwierig sein kann.
Meiner Meinung nach würde ich sagen, dass dies ein Fehler ist. Hier ist meine Begründung:
Wenn Sie den Aufruf zum Schließen des Präsentationsmodus mit einer asynchronen Verzögerung von etwa einer halben Sekunde abschließen, sollten Sie feststellen, dass das Programm nicht mehr abstürzt.
Dies deutet darauf hin, dass der Fehler ein unerwartetes Verhalten ist, das tief in der Schnittstelle von SwiftUI mit allen anderen UIKit-Codes zur Verwaltung der verschiedenen Ansichten liegt. Abhängig von Ihrem tatsächlichen Code stellen Sie möglicherweise fest, dass der Absturz tatsächlich nicht auftritt, wenn die Ansicht geringfügig komplexer ist. Wenn Sie beispielsweise von einer Ansicht zu einer Ansicht mit einer Liste wechseln und diese Liste leer ist, kommt es ohne asynchrone Verzögerung zu einem Absturz. Wenn Sie jedoch nur einen Eintrag in dieser Listenansicht haben und eine Schleifeniteration zum Generieren der übergeordneten Ansicht erzwingen, wird der Absturz nicht auftreten.
Ich bin mir nicht sicher, wie robust meine Lösung ist, den Entlassungsaufruf verzögert zu verpacken. Ich muss es noch viel mehr testen. Wenn Sie Ideen dazu haben, lassen Sie es mich bitte wissen! Ich würde mich sehr freuen, von Ihnen zu lernen!
quelle
.navigationBarItems()
Punkte funktioniert, dass dies ein Fehler ist.Das hat mich auch schon seit einiger Zeit frustriert. In den letzten Monaten hat sich die Xcode-Version, die Simulatorversion und der tatsächliche Gerätetyp und / oder die Version scheinbar zufällig von der Arbeit zur Nicht-Arbeit entwickelt. In letzter Zeit ist es für mich jedoch immer wieder gescheitert, und gestern habe ich mich eingehend damit befasst. Ich verwende derzeit Xcode Version 11.2.1 (11B500).
Es sieht so aus, als ob sich das Problem um die Navigationsleiste und die Art und Weise dreht, wie die Schaltflächen hinzugefügt wurden. Anstatt einen NavigationLink () für die Schaltfläche selbst zu verwenden, habe ich versucht, einen Standard-Button () mit einer Aktion zu verwenden, mit der eine @ State-Variable festgelegt wird, die einen versteckten NavigationLink aktiviert. Hier ist ein Ersatz für Roberts Elternansicht:
Für mich funktioniert dies sehr konsistent über alle Simulatoren und alle realen Geräte hinweg.
Hier sind meine Helferansichten:
Hier ist ein Beispiel für die Verwendung:
quelle
Dies ist ein schwerwiegender Fehler, und ich kann keinen geeigneten Weg finden, um ihn zu umgehen. Funktionierte gut in iOS 13 / 13.1, aber 13.2 stürzt ab.
Sie können es tatsächlich viel einfacher replizieren (dieser Code ist buchstäblich alles, was Sie brauchen).
Hoffe, Apple schafft es, da es sicherlich viele SwiftUI-Apps (einschließlich meiner) kaputt machen wird.
quelle
Um dieses Problem zu umgehen, habe ich basierend auf der obigen Antwort von Chuck H den NavigationLink als verstecktes Element gekapselt:
Dann können Sie es in einer Navigationsansicht verwenden (was entscheidend ist) und es über eine Schaltfläche in einer Navigationsleiste auslösen:
Schließen Sie dies in "// HACK" -Kommentare ein, damit Sie es ersetzen können, wenn Apple dies behebt.
quelle
Basierend auf den Informationen, die ihr bereitgestellt habt, und speziell einem Kommentar, den @Robert dazu gemacht hat, wo sich die Navigationsansicht befindet, habe ich einen Weg gefunden, das Problem zumindest in meinem speziellen Szenario zu umgehen.
In meinem Fall hatte ich eine TabView, die in einer Navigationsansicht wie folgt eingeschlossen war:
Dieser Code stürzt ab, da alle Benutzer in iOS 13.2 Bericht erstatten und in iOS 13.1 funktionieren. Nach einigen Recherchen habe ich eine Problemumgehung für diese Situation gefunden.
Grundsätzlich verschiebe ich die Navigationsansicht wie folgt auf jeden Bildschirm auf jeder Registerkarte:
Irgendwie widerspricht die SwiftUI-Prämisse der Einfachheit, aber es funktioniert unter iOS 13.2.
quelle
Xcode 11.2.1 Swift 5
VERSTANDEN! Ich habe ein paar Tage gebraucht, um das herauszufinden ...
In meinem Fall, wenn ich SwiftUI verwende, kommt es nur dann zu einem Absturz, wenn sich das Ende meiner Liste über den Bildschirm hinaus erstreckt und ich versuche, alle Listenelemente zu "verschieben". Am Ende habe ich herausgefunden, dass wenn ich zu viel "Zeug" unter der Liste () habe, es unterwegs abstürzt. Zum Beispiel hatte ich unter meiner Liste () einen Text (), einen Spacer (), einen Button (), einen Spacer () Button (). Wenn ich EINES dieser Objekte auskommentierte, konnte ich den Absturz plötzlich nicht mehr neu erstellen. Ich bin nicht sicher, was die Einschränkungen sind, aber wenn Sie diesen Absturz bekommen, versuchen Sie, Objekte unter Ihrer Liste zu entfernen, um zu sehen, ob es hilft.
quelle
Obwohl ich keine Abstürze sehen kann, weist Ihr Code einige Probleme auf:
Durch Festlegen des führenden Elements wird das Standardverhalten der Navigationsübergänge tatsächlich beendet. (Wischen Sie von der Vorderseite, um zu sehen, ob es funktioniert.)
Es muss also kein Knopf vorhanden sein. Lass es einfach so wie es ist und du hast einen kostenlosen Zurück-Button.
Und vergessen Sie laut HIG nicht , dass der Titel des Zurück-Buttons zeigen sollte, wohin es geht, nicht was es ist! Versuchen Sie also, einen Titel für die erste Seite festzulegen, um eine der beliebigen Zurück-Schaltflächen anzuzeigen.
quelle
FWIW - Die oben genannten Lösungen, die einen versteckten NavigationLink-Hack vorschlagen, sind immer noch die beste Problemumgehung in iOS 13.3b3. Ich habe auch einen FB7386339 für die Nachwelt eingereicht und wurde ähnlich wie bei anderen oben genannten FBs geschlossen: "Möglicher Fix identifiziert - Für ein zukünftiges Betriebssystem-Update".
Daumen drücken.
quelle
Es ist in iOS 13.3 gelöst. Aktualisieren Sie einfach Ihr Betriebssystem und Ihren xCode.
quelle
.buttonStyle(PlainButtonStyle())
Modifikator an und versuchen Sie es erneut. Lassen Sie mich wissen, wenn Sie eine Frage gestellt haben.