Je conçois une application qui inclut la fonction de récupération des données JSON et d'affichage d'une liste des éléments récupérés dans une vue de type FileBrowser. Dans cette vue, un utilisateur doit pouvoir cliquer sur un dossier pour plonger plus profondément dans l'arborescence de fichiers ou cliquer sur un fichier pour afficher des métadonnées sur ledit fichier.
J'ai observé que pendant que cela fonctionne, lorsque je clique sur un fichier ou un dossier, puis que je reviens en arrière et que je clique à nouveau dessus, le NavigationLink n'est pas déclenché et je suis bloqué sur la vue jusqu'à ce que je clique sur un autre NavigationLink.
Voici un gif illustrant ce problème.
Comme on le voit ici, lorsque je clique sur BlahBlah, j'active le NavigationLink et je suis amené à BlahBlah, puis quand je reviens en arrière et essaye de renaviguer vers BlahBlah, il devient gris, enregistrant que j'ai cliqué dessus ... mais ne m'y transporte jamais . Cliquer sur TestFile corrige cela et me permet de revenir à BlahBlah.
Les éléments de la liste sont créés avec les structures suivantes
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)
}
}
}
}
et appelé en vue avec navigationLinks comme suit
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)
}
}
}
Mon NavigationView est initialisé dans la vue ci-dessus (l'application a une vue d'onglet) comme suit
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)
}
Le NavigationConfigurator est une structure que j'utilise pour gérer la couleur de la barre de navigation. Il est configuré comme ça
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)
}
}
}
Je ne pense pas que ma NavigationConfigurator soit à l'origine de cela? Ce bogue se produit également dans d'autres liens de navigation de l'application, mais il était plus facile de le démontrer ici dans la vue FileBrowser.
Cela pourrait être un bug dans SwiftUI? Si c'est le cas, quelqu'un connaît-il un moyen de contourner ce problème? Si ce n'est pas le cas, que fais-je de mal?
NavigationLink
intérieurNavigationView
et le retirerNavigationView
duFileView
? J'ai vu quelques exemples ici qui le font de cette façon.NavigationLink
est à l'intérieur deFileView
qui est enveloppé dans unNavigationView
donc l'NavigationLink
est à l'intérieur d'unNavigationView
cellArray
?Réponses:
Eu le même problème - essayez ceci. J'appellerais cela un hack à supprimer lorsque le bogue dans swiftUI est corrigé.
Essentiellement, il semble que dans certaines circonstances (iOS 13.3 - Simulator?) Le NavigationLink n'est pas réinitialisé lorsque la vue de destination est supprimée de la pile de navigation. En guise de solution, nous devons régénérer le lien de navigation. C'est ce que fait le changement d'identifiant. Cela a corrigé mon problème.
Cependant, si vous avez des liens de navigation chaînés, c'est-à-dire un lien menant à une autre liste de liens, cette solution créera des effets secondaires; la pile revient à l'origine à la deuxième tentative pour afficher la dernière vue.
la source