首页 > 解决方案 > NavigationView 总是创建一个新视图

问题描述

我创建了 aNavigationView并且它可以工作,但是每次单击 aNavigationLink时,SwiftUI 都会重新创建目标视图并重置其中的每个属性。看这个例子:

struct NavView: View {
    @State var selectionIndex: Int? = nil
    let views = [
        DestinationView(viewNumber: 1),
        DestinationView(viewNumber: 2),
        DestinationView(viewNumber: 3)
    ]

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: self.views[0], tag: 0, selection: $selectionIndex) {
                    Text("View 1")
                }
                NavigationLink(destination: self.views[1], tag: 1, selection: $selectionIndex) {
                    Text("View 2")
                }
                NavigationLink(destination: self.views[2], tag: 0, selection: $selectionIndex) {
                    Text("View 3")
                }
            }

            self.views[0]
        }
    }
}
struct DestinationView: View {
    @State var viewNumber: Int
    @State var count = 0
    var body: some View {
        VStack {
            Text("View \(self.viewNumber)")
                .font(.largeTitle)
            Text("Count: \(self.count)")
            Button(action: {
                self.count += 1
            }) {
                Text("Increase counter")
            }
        }
    }
}

在此示例中,例如单击 View1 链接将打开 View 1。按下按钮会增加 count 属性。如果您然后单击 View2 按钮,然后返回 View1 按钮,则 count 属性将再次为零。

编辑

body正如评论中所建议的那样,我还尝试不存储视图并直接在其中创建它们。也不起作用:(

struct NavView: View {
    @State var selectionIndex: Int? = nil

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DestinationView(viewNumber: 1), tag: 0, selection: $selectionIndex) {
                    Text("View 1")
                }
                NavigationLink(destination: DestinationView(viewNumber: 2), tag: 1, selection: $selectionIndex) {
                    Text("View 2")
                }
                NavigationLink(destination: DestinationView(viewNumber: 3), tag: 2, selection: $selectionIndex) {
                    Text("View 3")
                }
            }

        }
    }
}

编辑 2 我也尝试在全球范围内存储视图,我也尝试过有和没有tag:selection:

标签: swiftui

解决方案


您的代码中的问题是,每当我们导航到 DestinationView 时,默认情况下每次将计数初始化为 0,所以技巧是我们必须更新计数值并将其保存在 NavView 中的某个位置。

首先,您必须创建DestinationViewModel以跟踪更新的计数值,如下所示

class DestinationViewModel: ObservableObject {

    @Published var viewNumber: Int
    @Published var count: Int

    init(_ viewNumber: Int, count: Int) {
        self.viewNumber = viewNumber
        self.count = count
    }
}

然后你可以访问你DestinationViewModelDestinationView

struct DestinationView: View {

    @EnvironmentObject var viewModel: DestinationViewModel

    var body: some View {
        VStack {
            Text("View \(viewModel.viewNumber)")
                .font(.largeTitle)
            Text("Count: \(viewModel.count)")
            Button(action: {
                self.viewModel.count += 1
            }) {
                Text("Increase counter")
            }
        }
    }
}

以下是您的更新NavView

class DestinationViewModelContainer: ObservableObject {
    @Published var viewModels: [DestinationViewModel]
    init(_ viewModels: [DestinationViewModel]) {
        self.viewModels = viewModels
    }
}

struct NavView: View {
    @EnvironmentObject var viewModelContainer: DestinationViewModelContainer

    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: DestinationView().environmentObject(viewModelContainer.viewModels[0])) {
                    Text("View 1")
                }
                NavigationLink(destination: DestinationView().environmentObject(viewModelContainer.viewModels[1])) {
                    Text("View 2")
                }
                NavigationLink(destination: DestinationView().environmentObject(viewModelContainer.viewModels[2])) {
                    Text("View 3")
                }
            }
        }
    }
}

在这里你可以NavView从下面的代码中调用你的

    let contentView = NavView().environmentObject(DestinationViewModelContainer([DestinationViewModel(1, count: 0), DestinationViewModel(2, count: 0),DestinationViewModel(3, count: 0)]))

希望它会帮助你。


推荐阅读