NavigationView始终创建一个新视图

时间:2020-04-03 07:55:12

标签: swiftui

我创建了一个NavigationView并可以使用,但是每次单击NavigationLink时,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链接可打开View1。按下按钮可增加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:

1 个答案:

答案 0 :(得分:0)

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

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

class DestinationViewModel: ObservableObject {

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

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

然后,您可以在DestinationViewModel中访问DestinationView

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

希望它会对您有所帮助。