【问题标题】:Trying to Update Previous View on Form Submission SwiftUI尝试更新表单提交 SwiftUI 的先前视图
【发布时间】:2021-08-04 00:26:46
【问题描述】:

我正在开展一个项目,用户可以在该项目中输入他们的股票交易(手数),然后查看一些统计数据。我的问题是,当从列表视图转到详细编辑视图并按保存时,列表视图不会收到有关此更改的通知(主视图也不会)

我总是可以尝试将以前的视图模型传递给编辑视图以使它们无效,但这对我来说似乎是一个 hack,所以我想知道我是否遗漏了 SwiftUI 的一些重要部分。

这是列表视图的代码

struct StockView: View {
    
    @ObservedObject var vm: StockViewModel
    
    init(_ symbol: String) {
        vm = StockViewModel(symbol)
    }
    
    var body: some View {
        List {
            ForEach(vm.lots, id: \.id) { lot in
                NavigationLink(destination: LotEditView(lot.id)) {
                    ...
                }
            }            
        }.navigationTitle("My Lots")
        .listStyle(PlainListStyle())
    }
}

以及编辑视图的代码

struct LotEditView: View {
    @Environment(\.presentationMode) var mode
    @ObservedObject var vm: LotEditViewModel
    
    init(_ id: UUID) {
        vm = LotEditViewModel(id)
    }
    
    var body: some View {
        VStack {
            Form {
                ...
            }
        }.navigationTitle("Edit Lot")
        .toolbar {
            Button("Done") {
                vm.save()
                mode.wrappedValue.dismiss()
            }
        }
    }
}

List ViewModel 使用股票名称进行初始化,然后使用该名称从模拟数据库中获取批次,然后将每个批次的 id 传递给 Edit ViewModel。 vm.save() 只是更新数据库,在这种情况下它只是一个我已经确认正在更新的数组。

【问题讨论】:

  • 您通常会有一个模型对象,您将其传递给每个视图模型的初始化程序。然后,视图模型负责将模型中的数据公开给您的视图,并提供更新模型的方法(例如您的 save 方法)。您的模型负责从数据库中获取数据并持久化更改。使用您当前的方法,尽管您的 StockViewModel 是一个可观察的对象,但没有任何东西可以从编辑屏幕更新其属性,因此它不会刷新视图

标签: ios swift mvvm swiftui


【解决方案1】:

因此,您要做的是拥有该 Mock 数据库的一个实例并将其注入到 viewModel 中。 我认为这里最简单的方法是将这个模拟数据库作为@StateObject。在初始视图中创建它(可能是 homeView 甚至 Appdelegate)并将其作为 environmentObject 传递给其他视图。

struct StockView: View {

    @ObservedObject var vm: StockViewModel
    @StateObject var dbService = MyMockDatabase()

    init(_ symbol: String) {
        vm = StockViewModel(dbService: dbService, symbol: symbol)
    }

    var body: some View {
        List {
            ForEach(vm.lots, id: \.id) { lot in
                NavigationLink(destination: LotEditView(lot.id).environmentObject(dbService)) {
                    ...
                }
            }            
        }.navigationTitle("My Lots")
        .listStyle(PlainListStyle())
    }
}

在你的下一个屏幕中使用它:

struct LotEditView: View {

    @Environment(\.presentationMode) var mode
    @EnvironmentObject var dbService: MyMockDatabase
    @ObservedObject var vm: LotEditViewModel

    init(_ id: UUID) {
        vm = LotEditViewModel(dbService: dbService, id: id)
    }

    var body: some View {
        VStack {
            Form {
                ...
            }
        }.navigationTitle("Edit Lot")
        .toolbar {
            Button("Done") {
                vm.save()
                mode.wrappedValue.dismiss()
            }
        }
    }
}

MockArray 看起来像:

class MyMockDatabase: ObservableObject {
    @Published var array = [...]
}

【讨论】:

    猜你喜欢
    • 2022-08-20
    • 1970-01-01
    • 1970-01-01
    • 2020-03-31
    • 2018-09-04
    • 1970-01-01
    • 2015-09-27
    • 2016-02-07
    • 1970-01-01
    相关资源
    最近更新 更多