如何将 @EnvironmentObject 与 List 结合使用
how to use a @EnvironmentObject in combination with a List
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()
}
}
}
没有错误,代码按预期运行。在我要重写我自己的代码之前(根据我学到的 solar 的经验教训),如果可以检查代码就更好了。
我对 SwiftUI 印象深刻!
如果你的 "source of truth" 是一些 "model instances" 的数组,而你只需要读取值,你可以像以前一样传递这些实例:
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 的状态,并且所有内容都将在各处自动神奇地更新!
下面的代码显示了一个带有 "list"、"detail" 和 "add" 的基本应用程序,因此您可以看到 'environment' 的运行情况(唯一需要注意的是您有以在点击保存按钮后手动点击 < 返回)。尝试一下,您会看到列表会神奇地更新。
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
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()
}
}
}
没有错误,代码按预期运行。在我要重写我自己的代码之前(根据我学到的 solar 的经验教训),如果可以检查代码就更好了。
我对 SwiftUI 印象深刻!
如果你的 "source of truth" 是一些 "model instances" 的数组,而你只需要读取值,你可以像以前一样传递这些实例:
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 的状态,并且所有内容都将在各处自动神奇地更新!
下面的代码显示了一个带有 "list"、"detail" 和 "add" 的基本应用程序,因此您可以看到 'environment' 的运行情况(唯一需要注意的是您有以在点击保存按钮后手动点击 < 返回)。尝试一下,您会看到列表会神奇地更新。
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