使用 EnvironmentObject 更新现有列表

问题描述

我有一个现有列表,但我希望能够向其中添加新项目。现在,我正在使用 @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)
    }

您甚至可以将 IDChecklistObject 属性更改为 id,然后添加 Identifiable 一致性。

    ForEach(event.checklist) { item in
        ChecklistDisplayRow()
            .environmentObject(item)
    }

(虽然很难说,因为我们没有看到您的其余代码,但是 item 是否真的需要作为 EnvironmentObject 传入,或者可以在ChecklistDisplayRow 的初始化程序?)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...