ios - 尝试更新表单提交 SwiftUI 上的先前 View

标签 ios swift mvvm swiftui

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

我总是可以尝试将以前的 View 模型传递到编辑 View 以使它们无效,但这对我来说似乎是一种黑客行为,所以我想知道我是否错过了 SwiftUI 的一些重要部分。

这是 ListView 的代码

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

以及编辑 View 的代码

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

ListView 模型使用股票名称进行初始化,然后使用它从模拟数据库中获取批处理,然后将每个批处理的 ID 传递给编辑 View 模型。 vm.save() 只是更新数据库,在本例中只是一个我已确认正在更新的数组。

最佳答案

因此,您想要做的就是拥有该 Mock 数据库的一个实例并将其注入(inject) viewModels 中。 我认为最简单的方法是将这个模拟数据库设置为 @StateObject。在初始 View (可能是 homeView 甚至 Appdelegate)中创建它,并将其作为环境对象传递给其他 View 。

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 = [...]
}

关于ios - 尝试更新表单提交 SwiftUI 上的先前 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68644104/

相关文章:

swift - 在 switch 语句中比较两个 `Any` 是否符合 `Equatable` 协议(protocol)

快速检查文本字段输入

c# - MVVM:如何只将属性读入 ViewModel?

mvvm - Observable Collection 在 MVVM 中的属性更改时通知

iphone - 安装 Xcode 4.2 后,命令/usr/bin/codesign 失败,退出代码为 1

iOS核心数据: Fetch child Magical Record data

javascript - 单击触摸设备 (iPad/iPhone) 上的任意位置以隐藏由 .hover() 切换的下拉菜单

javascript - React Native 选择器占位符

ios - 从 api 获取所有数据以及如何仅在 swift ios 中的单元格上附加标题

c# - 两种方式绑定(bind)到用户控件中的依赖属性并调用方法