问题描述
我有一个现有列表,但我希望能够向其中添加新项目。现在,我正在使用 @EnvironmentObject
,但是当我向数组添加元素时,视图没有更新?我在互联网上看到过使用 objectwillChange.send()
的解决方案,但作为 Swift 的初学者,我不知道如何操作它来做我想做的事。
类
class ChecklistObject: ObservableObject {
@Published var description: String
@Published var complete: Bool
let ID: Int
init(_ desc: String,_ complete: Bool,ID: Int){
description = desc
self.complete = complete
self.ID = ID
}
}
class Event: ObservableObject {
@Published var Name: String
@Published var CalendarID: Int
var timeStart: Date
var timeEnd: Date
@Published var checklist = [ChecklistObject]()
@Published var checklistSize = 0
init(_ eventName: String,_ calID: Int,_ timeStart: Date,_ timeEnd: Date) {
Name = eventName
CalendarID = calID
self.timeStart = timeStart
self.timeEnd = timeEnd
logger.log("Successfully created new event")
}
func newChecklistItem(Content: String){
objectwillChange.send()
checklist.append(ChecklistObject(Content,false,ID: getChecklistSize()))
//checklistSize = checklistSize + 1
}
func getChecklistSize() -> Int {
return checklist.count
}
}
列表
vstack (alignment: .leading) {
Text("Checklist")
.font(.title)
.bold()
ForEach(event.checklist.indices) { idx in
ChecklistdisplayRow()
.environmentObject(event.checklist[idx])
}
Spacer()
.frame(width: 360,height: 10)
Button(action: {
event.newChecklistItem(Content: "New item")
event.checklistSize = event.checklistSize + 1
}) {
HStack{
if #available(OSX 11.0,*) {
Image(systemName: "plus.circle")
} else {
Path{ path in
path.move(to: CGPoint(x: 10,y: 20))
path.addLine(to: CGPoint(x: 10,y:0))
path.move(to:CGPoint(x: 0,y: 10))
path.addLine(to: CGPoint(x: 20,y: 10))
}
}
Text("Add new item")
.font(.caption)
}
}
.buttonStyle(PlainButtonStyle())
}
提前致谢。
解决方法
这是因为您使用的 ForEach
版本。这个版本:
init(_ data: Range<Int>,content: @escaping (Int) -> Content)
“只读取提供数据的初始值,不需要跨更新识别视图。” (Apple's docs)
要获得动态更新,您需要使用 ForEach
的其他形式之一。
ForEach(event.checklist,id: \.ID) { item in
ChecklistDisplayRow()
.environmentObject(item)
}
您甚至可以将 ID
的 ChecklistObject
属性更改为 id
,然后添加 Identifiable
一致性。
ForEach(event.checklist) { item in
ChecklistDisplayRow()
.environmentObject(item)
}
(虽然很难说,因为我们没有看到您的其余代码,但是 item
是否真的需要作为 EnvironmentObject
传入,或者可以在ChecklistDisplayRow
的初始化程序?)