NavigationLink si blocca quando si tenta di rivisitare NavigationLink precedentemente selezionato in SwiftUI


10

Sto progettando un'app che include la funzione di recupero dei dati JSON e la visualizzazione di un elenco di elementi recuperati in una vista di tipo FileBrowser. In questa vista, un utente dovrebbe essere in grado di fare clic su una cartella per approfondire la struttura dei file o fare clic su un file per visualizzare alcuni metadati su tale file.

Ho osservato che mentre funziona, quando faccio clic su un file o su una cartella per tornare indietro e fare nuovamente clic su di esso, NavigationLink non viene attivato e rimango bloccato sulla vista fino a quando non faccio clic su un NavigationLink diverso.

Ecco una gif che dimostra questo problema.

Errore doppio tocco

Come visto qui, quando faccio clic su BlahBlah, sto attivando il NavigationLink e lo porto su BlahBlah, quindi quando torno indietro e provo a riorganizzare su BlahBlah, diventa grigio, registrando che ho cliccato su di esso ... ma poi non mi trasporta mai lì . Fare clic su TestFile risolve questo problema e mi consente di tornare a BlahBlah.

Le voci dell'elenco sono realizzate con le seguenti strutture

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)
                }
        }
    }
}

e chiamato in vista con navigationLinks come segue

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)
                    }
                }
            }

Il mio NavigationView è inizializzato nella vista sopra (l'app ha una vista a schede) come segue

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)
}

NavigationConfigurator è una struttura che utilizzo per gestire il colore della barra di navigazione. È impostato in questo modo

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)
        }
    }

}

Non penso che il mio NavigationConfigurator stia causando questo? Questo errore si verifica anche in altri collegamenti di navigazione nell'app, ma è stato più semplice dimostrarlo qui nella vista FileBrowser.

Questo potrebbe essere un bug in SwiftUI? Se lo è qualcuno conosce un modo per aggirare questo? In caso contrario, cosa sto facendo di sbagliato?


Non ne sono davvero sicuro. Ma non dovresti avvolgerlo NavigationLinkdentro ae NavigationViewrimuoverlo NavigationViewda FileView? Ho visto alcuni esempi qui che lo fanno in questo modo.
Giovanni,

@GiovanniTerlingen A meno che non fraintenda quello che stai dicendo, questo è quello che sto facendo. L' NavigationLinkinterno FileViewè racchiuso in un NavigationViewquindi NavigationLinkè avvolto all'interno di unNavigationView
Vapidant,

Fornisci un progetto eseguibile minimo. Non riesco a riprodurlo, quindi probabilmente non è uno dei bug di SwiftUI.
Mojtaba Hosseini

puoi fornire il codice sorgente completo in modo che io possa risolvere il tuo problema
Hardik Bar

come ti sei preparato cellArray?
E.Coms

Risposte:


5

Aveva lo stesso problema: prova questo. Lo definirei un hack da rimuovere quando il bug in swiftUI viene corretto.

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)

In sostanza sembra che in alcune circostanze (iOS 13.3 - Simulatore?) NavigationLink non venga ripristinato quando la vista di destinazione viene rimossa dallo stack di navigazione. Come soluzione, dobbiamo rigenerare il collegamento di navigazione. Questo è ciò che cambia l'id. Questo ha corretto il mio problema.

Tuttavia, se si dispone di NavigationLink concatenati, ovvero un collegamento che porta a un altro elenco di collegamenti, questa soluzione creerà effetti collaterali; la pila ritorna all'origine al secondo tentativo di mostrare l'ultima vista.


Questo errore è stato corretto nell'ultima versione di IOS. Sto contrassegnando questa come la risposta corretta a causa della risoluzione del problema così com'era, tuttavia, questo non dovrebbe essere un problema. Mi piace anche la tua spiegazione del problema. Grazie.
Vapidant,

Quando dici l'ultima versione di iOS, intendi 13.4 o una versione beta?
Ricardo Alves,

Vorrei sapere anche io. Quale versione funziona correttamente? Ho 13.3 (che è l'ultimo iOS in questo momento) e il problema è ancora lì.
Malva il

Credo che questo bug sia stato presentato in una versione beta di IOS 13.3 ma è stato corretto a partire da IOS 13.3 Beta 4.
Vapidant,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.