NavigationLink se congela cuando intenta volver a visitar NavigationLink en el que se hizo clic anteriormente en SwiftUI


10

Estoy diseñando una aplicación que incluye la función de recuperar datos JSON y mostrar una lista de elementos recuperados en una vista de tipo FileBrowser. En esta vista, un usuario debe poder hacer clic en una carpeta para profundizar en el árbol de archivos o hacer clic en un archivo para ver algunos metadatos sobre dicho archivo.

Observé que mientras esto funciona, cuando hago clic en un archivo o carpeta y luego vuelvo y hago clic en él nuevamente, el NavigationLink no se activa y estoy atascado en la vista hasta que hago clic en un NavigationLink diferente.

Aquí hay un gif que demuestra este problema.

Error de doble toque

Como se ve aquí, cuando hago clic en BlahBlah, estoy activando el NavigationLink y lo llevo a BlahBlah, luego, cuando navego hacia atrás y trato de volver a navegar a BlahBlah, se vuelve gris, registrando que hice clic en él ... pero nunca me transporta allí . Hacer clic en TestFile soluciona esto y me permite navegar de regreso a BlahBlah.

Los elementos de la lista están hechos con las siguientes estructuras

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

y aparece a la vista con los enlaces de navegación de la siguiente manera

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

Mi NavigationView se inicializa en la vista de arriba (la aplicación tiene una vista de pestañas) de la siguiente manera

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 es una estructura que uso para manejar el color de la barra de navegación. Está configurado así

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

}

¿No creo que mi NavigationConfigurator esté causando esto? Este error también ocurre en otros enlaces de navegación en la aplicación, pero fue más fácil demostrarlo aquí en la vista FileBrowser.

Esto podría ser un error en SwiftUI? Si es así, ¿alguien sabe una forma de evitar esto? Si no es así, ¿qué estoy haciendo mal?


No estoy muy seguro. ¿Pero no deberías envolverte NavigationLinkdentro de un NavigationViewy quitarlo NavigationViewdel FileView? He visto algunos ejemplos por aquí que lo hacen de esa manera.
Giovanni

@GiovanniTerlingen A menos que entienda mal lo que está diciendo, esto es lo que estoy haciendo. El NavigationLinkinterior FileViewestá envuelto en un, NavigationViewpor lo tanto, NavigationLinkestá envuelto dentro de unNavigationView
Vapidant

Proporcione un proyecto ejecutable mínimo. No puedo reproducir esto, así que probablemente no sea uno de los errores de SwiftUI.
Mojtaba Hosseini

se puede proporcionar el código fuente completo para que pueda resolver su problema
Hardik Bar

¿cómo se preparó cellArray?
E.Coms

Respuestas:


5

Tuve el mismo problema: prueba esto. Llamaría a esto un truco que se eliminará cuando se corrija el error en swiftUI.

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)

Esencialmente parece que en algunas circunstancias (iOS 13.3 - ¿Simulador?) El NavigationLink no se restablece cuando la vista de destino se elimina de la pila de navegación. Como solución, necesitamos regenerar el enlace de navegación. Esto es lo que hace cambiar la identificación. Esto corrigió mi problema.

Sin embargo, si tiene NavigationLinks que están encadenados, es decir, un enlace que conduce a otra lista de enlaces, entonces esta solución creará efectos secundarios; la pila vuelve al origen en el segundo intento de mostrar la última vista.


Este error se corrigió en la última versión de IOS. Estoy marcando esto como la respuesta correcta debido a que resolvió el problema tal como estaba, sin embargo, esto no debería ser un problema. También me gusta tu explicación del problema. Gracias.
Vapidant

Cuando dice la última versión de iOS, ¿quiere decir 13.4 o una versión beta?
Ricardo Alves

Me gustaría saber también ¿Qué versión funciona correcta? Tengo 13.3 (que es el último iOS en este momento) y el problema sigue ahí.
mallow

Creo que este error se presentó en una versión beta de IOS 13.3, pero se corrigió a partir de IOS 13.3 Beta 4.
Vapidant el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.