Swiftui嵌套导航

发布于 2025-02-05 05:44:52 字数 2848 浏览 4 评论 0 原文

当我导航时,下一页打开并快速关闭。为什么 ?

我在一个空项目上尝试了此问题,但没有遇到这个问题。为什么在我的项目中,导航在前进后会回来? 我想创建一个嵌套导航结构。

我的项目代码:

app

@main
struct FileApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    UserDefaults.standard.set(false, forKey: "_UIConstraintBasedLayoutLogUnsatisfiable")
                }
        }
    }
}

contentView:

struct ContentView: View {
    @StateObject var safeFileVM: SafeFileViewModel = SafeFileViewModel()
    var body: some View {
        NavigationView {
            AView(safeFileVM: safeFileVM)
        }
    }
}

aview:

struct AView: View {
    @ObservedObject var safeFileVM: SafeFileViewModel
    
    @State var currentLocation = ""
    @State var currentFolder: String = "Safe File"
    var body: some View {
        List(safeFileVM.arrayOfFiles, id: \.id) { folderItem in
            BView(safeFileVM: safeFileVM, currentFile: folderItem, currentLocation: currentLocation)
        }
        .navigationTitle(Text(currentFolder))
        .onAppear {
            safeFileVM.additionPath = currentLocation
            safeFileVM.takeArrayOfItems()
        }
    }
} 

bview:

struct BView: View {
    @ObservedObject var safeFileVM: SafeFileViewModel
    @State var currentFile: MyFile
    @State var currentLocation: String
    var body: some View {
        VStack {
            if currentFile.typeOfFile == "folder" {
                NavigationLink(currentFile.fileName) {
                    AView(safeFileVM: safeFileVM, currentLocation: currentLocation + "/" + currentFile.fileName, currentFolder: currentFile.fileName)
                }
                .isDetailLink(false)
            } else {
                Text(currentFile.fileName)
            }
        }
    }
}

空的项目代码:

contentView:

struct ContentView: View {
    var body: some View {
        NavigationView {
            AView()
                .navigationBarTitleDisplayMode(.inline)
        }
    }
}

aview:

struct AView: View {
    var body: some View {
        List(0..<5) { item in
            BView(title: item)
        }
    }
}

bview:

struct BView: View {
    var title: Int = 0
    var body: some View {
        NavigationLink("test \(title)") {
            AView()
        }
    }
}

When I navigate, the next page opens and closes quickly. Why ?

enter image description here

I tried this on an empty project and didn't run into this issue. Why in my project does the navigation come back after going forward?
I want to create a nested navigation structure.

MY PROJECT CODES:

App:

@main
struct FileApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    UserDefaults.standard.set(false, forKey: "_UIConstraintBasedLayoutLogUnsatisfiable")
                }
        }
    }
}

ContentView:

struct ContentView: View {
    @StateObject var safeFileVM: SafeFileViewModel = SafeFileViewModel()
    var body: some View {
        NavigationView {
            AView(safeFileVM: safeFileVM)
        }
    }
}

AView:

struct AView: View {
    @ObservedObject var safeFileVM: SafeFileViewModel
    
    @State var currentLocation = ""
    @State var currentFolder: String = "Safe File"
    var body: some View {
        List(safeFileVM.arrayOfFiles, id: \.id) { folderItem in
            BView(safeFileVM: safeFileVM, currentFile: folderItem, currentLocation: currentLocation)
        }
        .navigationTitle(Text(currentFolder))
        .onAppear {
            safeFileVM.additionPath = currentLocation
            safeFileVM.takeArrayOfItems()
        }
    }
} 

BView:

struct BView: View {
    @ObservedObject var safeFileVM: SafeFileViewModel
    @State var currentFile: MyFile
    @State var currentLocation: String
    var body: some View {
        VStack {
            if currentFile.typeOfFile == "folder" {
                NavigationLink(currentFile.fileName) {
                    AView(safeFileVM: safeFileVM, currentLocation: currentLocation + "/" + currentFile.fileName, currentFolder: currentFile.fileName)
                }
                .isDetailLink(false)
            } else {
                Text(currentFile.fileName)
            }
        }
    }
}

EMPTY PROJECT CODES:

ContentView:

struct ContentView: View {
    var body: some View {
        NavigationView {
            AView()
                .navigationBarTitleDisplayMode(.inline)
        }
    }
}

AView:

struct AView: View {
    var body: some View {
        List(0..<5) { item in
            BView(title: item)
        }
    }
}

BView:

struct BView: View {
    var title: Int = 0
    var body: some View {
        NavigationLink("test \(title)") {
            AView()
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

楠木可依 2025-02-12 05:44:52

在您的 aview 's onappear 中,您调用 takearrayofitems ,我认为,在该中,在该 .artayoffiles 属性中属性查看模型。

在您的层次结构中,您的顶级 aview 创建了链接到 bview s的项目列表,以及 bview> bview link to link to s的链接。 > Aview 再次。

当调用该嵌套 aview 时, onappear 再次调用 - 因此, takearrayofitems 可能正在突变文件夹的根层,这使链接进一步无效。路径;因此,导航视图将自己重置回根。

您可能应该注意确保层次结构的任何刷新不会使驱动您UI的数据无效。观看 /a>涉及SwiftUi如何使用对象标识在需要重新绘制接口时使用对象身份进行操作的 /a>。

而且,如果您的应用程序仅能是ios16,则您还可以访问SwiftUI中的新导航UI组件,该组件提供由一系列状态对象驱动的堆栈,从而使数据更改时保持堆栈位置更加容易。下。有关此主题的一个有用视频是 swiftui fackigation 来自WWDC22

In your AView's onAppear, you call takeArrayOfItems which, I presume, mutates the .arrayOfFiles property in the view model.

In your hierarchy, your top level AView creates a list of items which link to BViews, and the folder links in BView link to AView again.

When that nested AView is called, onAppear is called again - so takeArrayOfItems is probably mutating the root layer of folders, which invalidates the links further down the path; and so the navigation view resets itself back to the root.

You should probably take care to ensure that any refreshing of your hierarchy doesn't invalidate the data driving your UI. It might also be useful to watch Demystifying SwiftUI from WWDC21 which goes into, among other things, how SwiftUI uses object identity to work out when the interface needs to be redrawn.

And if your app can be iOS16 only, you'll also have access to the new navigation UI components in SwiftUI, which provide for stacks to be driven by an array of state objects, making it much easier to maintain stack position when data is changing underneath. A useful video on this topic is The SwiftUI cookbook for navigation from WWDC22.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文