Swiftui 如何将@EnvironmentObject与列表结合使用

Swiftui 如何将@EnvironmentObject与列表结合使用,swiftui,Swiftui,Anlil答案中的基本应用程序代码运行良好。如果我用多维字符串数组编辑数据模型,使其更像我的数据模型,我会得到如下结果: import SwiftUI import Combine struct ContentView: View { @EnvironmentObject var dm: DataManager var body: some View { NavigationView { List { Na

Anlil答案中的基本应用程序代码运行良好。如果我用多维字符串数组编辑数据模型,使其更像我的数据模型,我会得到如下结果:

import SwiftUI
import Combine

struct ContentView: View {
    @EnvironmentObject var dm: DataManager

    var body: some View {
        NavigationView {
            List {
               NavigationLink(destination:AddView().environmentObject(self.dm)) {
                    Image(systemName: "plus.circle.fill").font(.system(size: 30))
                }
                ForEach(dm.array, id: \.self) { item in
                    NavigationLink(destination: DetailView(item: item)) {
                        Text(item[0])
                    }
                }
            }
        }
    }
}

struct DetailView: View {
    var item : [String] = ["", "", ""]
    var body: some View {
        VStack {
            Text(item[0])
            Text(item[1])
            Text(item[2])
        }
    }
}

struct AddView: View {
    @EnvironmentObject var dm: DataManager
    @State var item0 : String = "" // needed by TextField
    @State var item1 : String = "" // needed by TextField
    @State var item2 : String = "" // needed by TextField
    @State var item : [String] = ["", "", ""]
    var body: some View {
        VStack {
            TextField("Write something", text: $item0)
                    .textFieldStyle(.roundedBorder)
                    .padding(.horizontal)
            TextField("Write something", text: $item1)
                    .textFieldStyle(.roundedBorder)
                    .padding(.horizontal)
            TextField("Write something", text: $item2)
                    .textFieldStyle(.roundedBorder)
                    .padding(.horizontal)
            Button(action: {
                self.item = [self.item0, self.item1, self.item2]
                print(self.item)
                self.dm.array.append(self.item)
            }) {
                Text("Save")
            }
        }
    }
}

class DataManager: BindableObject {
    var willChange = PassthroughSubject<Void, Never>()
    var array : [[String]] = [["Item 1","Item 2","Item 3"],["Item 4","Item 5","Item 6"],["Item 7","Item 8","Item 9"]] {
        didSet {
            willChange.send()
        }
    }
}
导入快捷界面
进口联合收割机
结构ContentView:View{
@环境对象变量dm:DataManager
var body:一些观点{
导航视图{
名单{
NavigationLink(目标:AddView().environmentObject(self.dm)){
图像(systemName:“plus.circle.fill”).font(.system(大小:30))
}
ForEach(dm.array,id:\.self){item in
导航链接(目的地:详细视图(项目:项目)){
文本(项目[0])
}
}
}
}
}
}
结构详细视图:视图{
变量项:[字符串]=[“”,“”,“”]
var body:一些观点{
VStack{
文本(项目[0])
案文(第[1]项)
案文(项目[2])
}
}
}
结构AddView:View{
@环境对象变量dm:DataManager
@状态变量item0:String=”“//TextField需要
@状态变量item1:String=”“//TextField需要
@State var item2:String=”“//TextField需要
@状态变量项:[String]=[“”,“”,“”]
var body:一些观点{
VStack{
TextField(“写点什么”,text:$item0)
.textFieldStyle(.roundedBorder)
.padding(.卧式)
TextField(“写点什么”,text:$item1)
.textFieldStyle(.roundedBorder)
.padding(.卧式)
TextField(“写点什么”,text:$item2)
.textFieldStyle(.roundedBorder)
.padding(.卧式)
按钮(操作:{
self.item=[self.item0、self.item1、self.item2]
打印(self.item)
self.dm.array.append(self.item)
}) {
文本(“保存”)
}
}
}
}
类DataManager:BindableObject{
var willChange=PassthroughSubject()
变量数组:[[String]=[[“第1项”、“第2项”、“第3项”]、[“第4项”、“第5项”、“第6项”]、[“第7项”、“第8项”、“第9项”]{
迪塞特{
willChange.send()
}
}
}
没有错误,代码按预期运行。在我重写自己的代码之前(用我从solar学到的经验教训),如果代码可以检查一下就好了

我对迅捷印象深刻

如果您的“真理之源”是一些“模型实例”的数组,您只需要读取值,就可以像前面一样传递这些实例:

import SwiftUI
import Combine

struct ContentView: View {
    @EnvironmentObject var dm: DataManager

    var body: some View {
        NavigationView {
            List(dm.array, id: \.self) { item in
                NavigationLink(destination: DetailView(item: item)) {
                    Text(item)
                }
            }
        }
    }
}

struct DetailView: View {
    var item : String
    var body: some View {
        Text(item)
    }
}

class DataManager: BindableObject {
    var willChange = PassthroughSubject<Void, Never>()
    let array = ["Item 1", "Item 2", "Item 3"]
}


#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environmentObject(DataManager())
    }
}
#endif
导入快捷界面
进口联合收割机
结构ContentView:View{
@环境对象变量dm:DataManager
var body:一些观点{
导航视图{
列表(dm.array,id:\.self){中的项
导航链接(目的地:详细视图(项目:项目)){
文本(项目)
}
}
}
}
}
结构详细视图:视图{
变量项:字符串
var body:一些观点{
文本(项目)
}
}
类DataManager:BindableObject{
var willChange=PassthroughSubject()
让数组=[“项目1”、“项目2”、“项目3”]
}
#如果调试
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView().environmentObject(DataManager())
}
}
#恩迪夫
仅当某些视图能够操作实例中的数据时,才需要传递EnvironmentObject。。。在这种情况下,您可以轻松地更新EnvironmentObject的状态,所有内容都将自动神奇地更新到所有位置

下面的代码显示了一个带有“列表”、“详细信息”和“添加”的基本应用程序,因此您可以看到“环境”正在运行(唯一需要注意的是,您必须在点击保存按钮后手动点击<返回)。试试看,你会看到列表会神奇地更新

import SwiftUI
import Combine

struct ContentView: View {
    @EnvironmentObject var dm: DataManager

    var body: some View {
        NavigationView {
            List {
               NavigationLink(destination:AddView().environmentObject(self.dm)) {
                    Image(systemName: "plus.circle.fill").font(.system(size: 30))
                }
                ForEach(dm.array, id: \.self) { item in
                    NavigationLink(destination: DetailView(item: item)) {
                        Text(item)
                    }
                }
            }
        }
    }
}

struct DetailView: View {
    var item : String
    var body: some View {
        Text(item)
    }
}

struct AddView: View {
    @EnvironmentObject var dm: DataManager
    @State var item : String = "" // needed by TextField
    var body: some View {
        VStack {
            TextField("Write something", text: $item)
                    .textFieldStyle(.roundedBorder)
                    .padding(.horizontal)
            Button(action: {
                self.dm.array.append(self.item)
            }) {
                Text("Save")
            }
        }
    }
}

class DataManager: BindableObject {
    var willChange = PassthroughSubject<Void, Never>()
    var array : [String] = ["Item 1", "Item 2", "Item 3"] {
        didSet {
            willChange.send()
        }
    }
}


#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environmentObject(DataManager())
    }
}
#endif
导入快捷界面
进口联合收割机
结构ContentView:View{
@环境对象变量dm:DataManager
var body:一些观点{
导航视图{
名单{
NavigationLink(目标:AddView().environmentObject(self.dm)){
图像(systemName:“plus.circle.fill”).font(.system(大小:30))
}
ForEach(dm.array,id:\.self){item in
导航链接(目的地:详细视图(项目:项目)){
文本(项目)
}
}
}
}
}
}
结构详细视图:视图{
变量项:字符串
var body:一些观点{
文本(项目)
}
}
结构AddView:View{
@环境对象变量dm:DataManager
@状态变量项:String=”“//TextField需要
var body:一些观点{
VStack{
TextField(“写点什么”,text:$item)
.textFieldStyle(.roundedBorder)
.padding(.卧式)
按钮(操作:{
self.dm.array.append(self.item)
}) {
文本(“保存”)
}
}
}
}
类DataManager:BindableObject{
var willChange=PassthroughSubject()
变量数组:[字符串]=[“项目1”、“项目2”、“项目3”]{
迪塞特{
willChange.send()
}
}
}
#如果调试
结构内容视图\u预览:PreviewProvider{
静态var预览:一些视图{
ContentView().environmentObject(DataManager())
}
}
#恩迪夫

Hi Enlil,我用当前的数据模型编辑了我的问题。如果我正确地理解了您的意思,那么我必须将我的数据模型调整为一个数组(参见上面的代码)。然后。。。我和接收者/发送者部分有什么关系?嗨,Enlil,我再次编辑了我的问题。。。正在尝试更新数据模型以获得更多维度。嗨,Enlil,代码现在可以工作了。在我重写自己的代码之前,你能检查一下吗?谢谢你抽出时间来教书。