首页 > 解决方案 > 基于 Bool 更新列表 - SwiftUI

问题描述

我正在尝试创建一个清单视图,其中包含从 .json 解码的项目列表,在点击该项目时,它会将其标记为已完成。我正在努力的是在您将项目标记为已完成时更新列表。目前它只会在关闭视图然后再次打开后更新。

这是视图:

struct ChecklistView: View {
    
    @Environment(\.presentationMode) var presentationMode
    @ObservedObject var checkList: Checklist
    
    var body: some View {
        VStack {
            HStack {
                Text(checkList.checklist)
                    .font(.title)
                Spacer()
                Button("Close") {
                    presentationMode.wrappedValue.dismiss()
                }
            }
            List(checkList.actions, id: \.id) { item in
                if item.action == "" {
                    Text(item.name).italic()
                        .multilineTextAlignment(.center)
                        .font(.callout)
                        .foregroundColor(.gray)
                        .frame(maxWidth: .infinity)
                } else {
                    Button(action: {
                        item.completed.toggle()
                    }) {
                        if item.completed {
                            HStack {
                                Image(systemName: "checkmark.square")
                                    .foregroundColor(.green)
                                Text(item.name)
                                Spacer()
                                Text(item.action)
                                    .font(.caption)
                                    .foregroundColor(.gray)
                            }
                        } else {
                            HStack {
                                Image(systemName: "square")
                                Text(item.name)
                                Spacer()
                                Text(item.action)
                                    .font(.caption)
                                    .foregroundColor(.gray)
                            }
                        }
                    }
                }
            }
        }.padding()
    }
}

这是清单的类:

class Checklist: Codable, Identifiable, ObservableObject {
    enum CodingKeys: CodingKey {
        case checklist
        case actions
    }
    var id = UUID()
    var checklist: String
    var actions: [Action]
    
    class Action: Codable, Identifiable, ObservableObject {
        enum CodingKeys: CodingKey {
            case name
            case action
        }
        var id = UUID()
        var name: String
        var action: String
        @Published var completed: Bool = false
    }
}

任何帮助,将不胜感激。

标签: iosswiftswiftui

解决方案


问题出在您的Checklist班级中——您将其设置为@ObservableObject,但您没有可观察的属性(即@Published)。相反,您有一个Actions 数组,它们也是类,它们发布一个completed属性。但是,您List看不到这一点,因为它只是在actions查看清单上的静态属性。

我建议将您Action的 s 转换为结构并使其成为actions@Published。

class Checklist: Identifiable, ObservableObject {
    var id = UUID()
    var checklist: String = ""
    @Published var actions: [Action] = []
    
    struct Action: Identifiable {
        enum CodingKeys: CodingKey {
            case name
            case action
        }
        var id = UUID()
        var name: String
        var action: String
        var completed: Bool = false
    }
}

有警告。一是您检查项目的逻辑将变得更加复杂。一种可能:

checkList.actions = checkList.actions.map {
                            if $0.id == item.id {
                                var updatedItem = item
                                updatedItem.completed.toggle()
                                return updatedItem
                            }
                            return $0
                        }

另一个是在 Checklist 上拥有 @Published 属性Codable最初会中断。这有很多可能性,包括将Checklist自身存储在不同的包装器中,进行更多的手动解码等。

所以,仍然需要做出一些决定,但这应该让你开始。


推荐阅读