如何将@EnvironmentObject与List结合使用

时间:2019-07-28 17:04:34

标签: swiftui

答案中基本应用程序的代码有效。如果我将数据模型编辑得更像我的数据模型,我会得到类似的东西:

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 item1 : String = "" // needed by TextField
    @State var item2 : String = "" // needed by TextField
    @State var item3 : String = "" // needed by TextField
    var item : DataManager()
    var body: some View {
        VStack {
            TextField("Write something", text: $item1)
                    .textFieldStyle(.roundedBorder)
                    .padding(.horizontal)
            TextField("Write something", text: $item2)
                    .textFieldStyle(.roundedBorder)
                    .padding(.horizontal)
            TextField("Write something", text: $item3)
                    .textFieldStyle(.roundedBorder)
                    .padding(.horizontal)
            Button(action: {
                self.item.een = $item1
                self.item.twee = $item2
                self.item.drie = $item3
                self.dm.array.append(self.item)
            }) {
                Text("Save")
            }
        }
    }
}

class DataManager: BindableObject {
    var willChange = PassthroughSubject<Void, Never>()
    var array = [(een: "1",twee: "2",drie: "3"), (een: "4",twee: "5",drie: "6"), (een: "7",twee: "8",drie: "9")] {
        didSet {
            willChange.send()
        }
    }
}

#if DEBUG
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView().environmentObject(DataManager())
    }
}
#endif

仍然存在一些错误:

  1. 在第一个调用中缺少参数“ item”的参数 NavigationLink
  2. 模式中意外的初始化器;您是要使用'='吗? @的 “ item”的声明
  3. “ DataManager”类型的值没有成员“ een” /“ twee” /“ drie”
  4. 无法将类型“ DataManager”的值转换为预期的参数类型 '(een:字符串,twee:字符串,drie:字符串)'@附加

1 个答案:

答案 0 :(得分:1)

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

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

仅当某些视图能够操纵实例内部的数据时,才需要传递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