NavigationLink friert ein, wenn versucht wird, zuvor angeklickte NavigationLink in SwiftUI erneut aufzurufen

10

Ich entwerfe eine App, die die Funktion zum Abrufen von JSON-Daten und zum Anzeigen einer Liste der abgerufenen Elemente in einer FileBrowser-Typansicht enthält. In dieser Ansicht sollte ein Benutzer in der Lage sein, auf einen Ordner zu klicken, um tiefer in den Dateibaum einzutauchen, oder auf eine Datei klicken, um einige Metadaten zu dieser Datei anzuzeigen.

Ich habe festgestellt, dass während dies funktioniert, wenn ich auf eine Datei oder einen Ordner klicke und dann zurück gehe und erneut darauf klicke, der NavigationLink nicht ausgelöst wird und ich in der Ansicht stecken bleibe, bis ich auf einen anderen NavigationLink klicke.

Hier ist ein GIF, das dieses Problem demonstriert.

Double Tap Bug

Wie hier zu sehen ist, wenn ich auf BlahBlah klicke, aktiviere ich den Navigationslink und werde zu BlahBlah weitergeleitet. Wenn ich dann zurück navigiere und versuche, zu BlahBlah zurückzukehren, wird es grau und registriert, dass ich darauf geklickt habe ... aber dann transportiere ich mich nie dorthin . Durch Klicken auf TestFile wird dies behoben und ich kann zurück zu BlahBlah navigieren.

Die Listenelemente werden mit den folgenden Strukturen erstellt

private struct FileCell{
    var FileName: String
    var FileType: String
    var FileID: String = ""
    var isContainer: Bool
}

private struct constructedCell: View{

    var FileType: String
    var FileName: String
    var FileID: String

    var body: some View {
        return
            HStack{
                VStack(alignment: .center){
                    Image(systemName: getImage(FileType: FileType)).font(.title).frame(width: 50)
                }
                Divider()
                VStack(alignment: .leading){
                    Text(FileName).font(.headline)
                        .multilineTextAlignment(.leading)
                    Text(FileID)
                        .font(.caption)
                        .multilineTextAlignment(.leading)
                }
        }
    }
}

und mit Navigationslinks wie folgt aufgerufen

List(cellArray, id: \.FileID) { cell in
                if (cell.isContainer) {
                    NavigationLink(destination: FileView(path: "/\(cell.FileID)", displaysLogin: self.$displaysLogin).navigationBarTitle(cell.FileName)){
                        constructedCell(FileType: cell.FileType, FileName: cell.FileName, FileID: cell.FileID)
                    }
                } else {
                    NavigationLink(destination: DetailView(FileID: cell.FileID).navigationBarTitle(cell.FileName)){
                        constructedCell(FileType: cell.FileType, FileName: cell.FileName, FileID: cell.FileID)
                    }
                }
            }

Meine Navigationsansicht wird in der obigen Ansicht (die App verfügt über eine Registerkartenansicht) wie folgt initialisiert

TabView(selection: $selection){
               NavigationView{
                    FileView(displaysLogin: self.$displaysLogin)
                        .navigationBarTitle("Home", displayMode: .inline)
                        .background(NavigationConfigurator { nc in
                            nc.navigationBar.barTintColor = UIColor.white
                            nc.navigationBar.titleTextAttributes = [.foregroundColor : UIColor.black]
                        })
                }
                .font(.title)
                .tabItem {
                    VStack {
                        Image(systemName: "folder.fill")
                        Text("Files")
                    }
                }
                .tag(0)
}

Der NavigationConfigurator ist eine Struktur, die ich zum Behandeln der Farbe der Navigationsleiste verwende. Es ist so aufgebaut

struct NavigationConfigurator: UIViewControllerRepresentable {
    var configure: (UINavigationController) -> Void = { _ in }

    func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationConfigurator>) -> UIViewController {
        UIViewController()
    }
    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
        if let nc = uiViewController.navigationController {
            self.configure(nc)
        }
    }

}

Ich glaube nicht, dass mein NavigationConfigurator dies verursacht? Dieser Fehler tritt auch in anderen Navigationslinks in der App auf, aber es war am einfachsten, ihn hier in der FileBrowser-Ansicht zu demonstrieren.

Dies könnte ein Fehler in SwiftUI sein? Wenn ja, kennt jemand einen Weg, dies zu umgehen? Wenn nicht, was mache ich falsch?

Vapidant
quelle
Ich bin mir nicht ganz sicher. Aber sollten Sie sich nicht NavigationLinkin ein einwickeln NavigationViewund NavigationViewaus dem entfernen FileView? Ich habe hier einige Beispiele gesehen, die das so machen.
Giovanni
@GiovanniTerlingen Wenn ich nicht falsch verstehe, was Sie sagen, ist es das, was ich tue. Das NavigationLinkist innen, in FileViewdas ein eingewickelt ist, NavigationViewdaher ist das in ein NavigationLinkeingewickeltNavigationView
Vapidant
Bitte geben Sie ein lauffähiges Mindestprojekt an. Ich kann das nicht reproduzieren, daher ist es wahrscheinlich nicht einer der Fehler von SwiftUI.
Mojtaba Hosseini
Können
Wie hast du dich vorbereitet cellArray?
E.Coms

Antworten:

5

Hatte das gleiche Problem - versuchen Sie dies. Ich würde dies einen Hack nennen, der entfernt werden soll, wenn der Fehler in swiftUI behoben ist.

struct ListView: View {
@State private var destID = 0
...
var body: some View {
...
  NavigationLink(destination: FileView(path: "/\(cell.FileID)", displaysLogin: self.$displaysLogin)
   .navigationBarTitle(cell.FileName) 
   .onDisappear() { self.destID = self.destID + 1 }
  ){
   constructedCell(FileType: cell.FileType, FileName: cell.FileName, FileID: cell.FileID) 
  }.id(destID)

Im Wesentlichen scheint es, dass unter bestimmten Umständen (iOS 13.3 - Simulator?) Der NavigationLink nicht zurückgesetzt wird, wenn die Zielansicht aus dem Navigationsstapel entfernt wird. Um dies zu umgehen, müssen wir den Navigationslink neu generieren. Dies ist, was das Ändern der ID bewirkt. Dies hat mein Problem behoben.

Wenn Sie jedoch verkettete Navigationslinks haben, dh einen Link, der zu einer anderen Liste von Links führt, führt diese Lösung zu Nebenwirkungen. Der Stapel kehrt beim zweiten Versuch, die letzte Ansicht anzuzeigen, zum Ursprung zurück.

VJK
quelle
Dieser Fehler wurde in der neuesten IOS-Version behoben. Ich markiere dies als die richtige Antwort, da das Problem in seiner jetzigen Form gelöst wurde. Dies sollte jedoch kein Problem sein. Ich mag auch Ihre Erklärung des Problems. Vielen Dank.
Vapidant
Wenn Sie die neueste iOS-Version sagen, meinen Sie 13.4 oder eine Beta-Version?
Ricardo Alves
Ich würde es auch gerne wissen. Welche Version funktioniert richtig? Ich habe 13.3 (das ist das neueste iOS im Moment) und das Problem ist immer noch da.
Malve
Ich glaube, dieser Fehler wurde in einem IOS 13.3 Beta Build präsentiert, wurde aber ab IOS 13.3 Beta 4
behoben.