尝试重新访问SwiftUI中先前单击的NavigationLink时,NavigationLink冻结 [英] NavigationLink freezes when trying to revisit previously clicked NavigationLink in SwiftUI

查看:580
本文介绍了尝试重新访问SwiftUI中先前单击的NavigationLink时,NavigationLink冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个应用程序,该应用程序包括检索JSON数据并在FileBrowser类型视图中显示检索到的项目列表的功能.在这种视图下,用户应该能够单击文件夹以更深入地进入文件树,或者单击文件以查看有关该文件的一些元数据.

I am designing an app that includes the function of retrieving JSON data and displaying a list of retrieved items in a FileBrowser type view. In this view, a user should be able to click on a folder to dive deeper into the file tree or click on a file to view some metadata about said file.

我观察到,在这种情况下,当我单击文件或文件夹然后再次单击并单击它时,不会触发NavigationLink,并且在单击其他导航链接之前,我一直停留在视图上.

I've observed that while this is working, when I click on a file or folder then go back and click on it again, the NavigationLink is not triggered and I am stuck on the view until I click into a different NavigationLink.

这是展示此问题的gif文件.

Here is a gif demonstrating this problem.

如此处所示,当我单击BlahBlah时,我正在激活NavigationLink并转到BlahBlah,然后当我向后导航并尝试重新导航至BlahBlah时,它变成灰色,表明我单击了它……但是从未带我去那里.单击TestFile可以解决此问题,并使我可以导航回BlahBlah.

As seen here, when I click on BlahBlah I am activating the NavigationLink and taken to BlahBlah, then when I navigate back and try to renavigate to BlahBlah, it becomes grey, registering that I clicked on it... but then never transports me there. Clicking on TestFile fixes this and allows me to navigate back to BlahBlah.

列表项由以下结构组成

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

,并通过以下导航链接进入视图

and called into view with navigationLinks as follows

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

我的NavigationView在上面的视图(应用程序具有选项卡视图)中初始化,如下所示

My NavigationView is initialized in the view above (the app has a tab view) this as follows

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是我用于处理navigationBar颜色的结构.像这样设置

The NavigationConfigurator is a struct I use for handling the color of the navigationBar. It is set up like so

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

}

我不认为我的NavigationConfigurator引起了这个问题?该错误也发生在应用程序中的其他NavigationLinks中,但是最容易在FileBrowser视图中进行演示.

I do not think my NavigationConfigurator is causing this? This bug also happens in other navigationLinks in the app, but it was easiest to demonstrate it here in the FileBrowser view.

这可能是SwiftUI中的错误吗?如果是,是否有人知道解决此问题的方法?如果不是,那我在做什么错了?

This might be a bug in SwiftUI? If it is does anyone know a way to work around this? If it isn't, what am I doing wrong?

推荐答案

遇到了同样的问题-试试这个.当swiftUI中的错误得到纠正后,我将其称为要删除的黑客.

Had the same issue - try this. I would call this a hack to be removed when the bug in swiftUI is corrected.

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)

从本质上来说,似乎在某些情况下(iOS 13.3-Simulator?),当从导航堆栈中删除目标视图时,不会重置NavigationLink.作为解决方法,我们需要重新生成导航链接.这就是更改id的作用.这解决了我的问题.

Essentially it seems that in some circumstances (iOS 13.3 - Simulator?) the NavigationLink is not reset when the destination view is removed from the navigation stack. As a work around we need to regenerate the Navigation Link. This is what changing the id does. This corrected my issue.

但是,如果您有链式链接的NavigationLink,即指向另一个链接列表的链接,则此解决方案会产生副作用;在第二次尝试显示最后一个视图时,堆栈将返回到原点.

However if you have NavigationLinks that are chained, that is a link that leads to another list of links, then this solution will create side effects; the stack returns to the origin at the second attempt to show the last view.

这篇关于尝试重新访问SwiftUI中先前单击的NavigationLink时,NavigationLink冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆