列表项未更新

List item is not being updated

所以我有一个 ViewList 个接受对象的子视图。这些对象来自我的数据管理器中的数组。

struct ContentView: View {
@ObservedObject var manager = AppConnectivityManager.shared

var body: some View {
    
        List {
            ForEach(manager.goals, id: \.id) { goal in
                let _ = print("goal in foreach: \(goal.goal.completitionCount) + title: \(goal.goal.title)")
                GoalView(goalWrapper:goal)
            }.listRowBackground(Color.clear)
        }
    
    }
}

这部分效果很好,每次我更新管理器对象时都会触发更新。

问题是我的 GoalView(goalWrapper:goal) 只在代码第一次运行时更新一次,但当它应该被刷新时它保持不变。目标视图中的 print("progress: 语句始终打印相同的值,但列表中的打印语句得到更新。我可能错过了这个概念,但我虽然可以将 ObservedObject 传递到子视图下,并且当 manager 也更新时它也会更新,但事实并非如此。

struct GoalView: View {

@ObservedObject var goalWrapper: GoalWrapper

var body: some View {
    let _ = print("progress: \(self.goalWrapper.goal.completitionCount) + daily: \(self.goalWrapper.goal.dailyNotificationCount) + title: \(self.goalWrapper.goal.title)")
    ZStack(content: {
        GoalAnimationView(goalWrapper: self.goalWrapper).cornerRadius(10)
        VStack(alignment: .leading, spacing: nil, content: {
            Text(goalWrapper.goal.title).foregroundColor(.black).padding(.leading, 8)
                .padding(.trailing, 8)
                .padding(.top, 4)
            HStack(alignment: .center,content: {
                Text("\(goalWrapper.goal.completitionCount)/\(goalWrapper.goal.dailyNotificationCount)").padding(.top, 2).padding(.trailing, 85).padding(.bottom, 6)
                Text("\(goalWrapper.goal.completitionCount)").padding(.top, 2).padding(.trailing, 12).padding(.bottom, 12).font(.title)
            }).frame(minWidth: 0, maxWidth: .infinity, minHeight: 0,maxHeight: 35,alignment: .trailing).background(Color.clear)


        }).listRowPlatterColor(Color.blue).frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, alignment: .leading).cornerRadius(10)
        
    })
  }
}

这里是GoalWrapperclass

public class GoalWrapper: ObservableObject, Hashable {

    public static func == (lhs: GoalWrapper, rhs: GoalWrapper) -> Bool {
        return lhs.goal.id == rhs.goal.id
    }

    public func hash(into hasher: inout Hasher) {
         hasher.combine(goal.id)
    }

    @Published var goal: Goal!
    let id: String
    init(goal: Goal) {
        self.goal = goal
        self.id = goal.id
   }
}

有什么方法可以将更新传递给列表子视图吗?我发现其他一些人对列表有问题,并将绑定传递给列表中的视图。这是唯一的方法吗?

您不需要 GoalWrapper。您应该将 goal 作为 Binding<Goal>ContentView 传递到 GoalView

如果您在 ForEach 所在位置收到警告,则您在 Goal 上有 id 属性,但可能需要遵守 Identifiable 协议.否则将 , id: \.id 添加回去。

代码:

struct ContentView: View {
    @ObservedObject var manager = AppConnectivityManager.shared

    var body: some View {
        List {
            ForEach($manager.goals) { $goal in
                let _ = print("goal in foreach: \(goal.completitionCount) + title: \(goal.title)")
                GoalView(goal: $goal)
            }.listRowBackground(Color.clear)
        }
    }
}
struct GoalView: View {
    @Binding var goal: Goal

    var body: some View {
        let _ = print("progress: \(goal.completitionCount) + daily: \(goal.dailyNotificationCount) + title: \(goal.title)")
        ZStack(content: {
            //GoalAnimationView(goalWrapper: self.goalWrapper).cornerRadius(10) // This needs changing too
            VStack(alignment: .leading, spacing: nil, content: {
                Text(goal.title).foregroundColor(.black).padding(.leading, 8)
                    .padding(.trailing, 8)
                    .padding(.top, 4)
                HStack(alignment: .center,content: {
                    Text("\(goal.completitionCount)/\(goal.dailyNotificationCount)").padding(.top, 2).padding(.trailing, 85).padding(.bottom, 6)
                    Text("\(goal.completitionCount)").padding(.top, 2).padding(.trailing, 12).padding(.bottom, 12).font(.title)
                }).frame(minWidth: 0, maxWidth: .infinity, minHeight: 0,maxHeight: 35,alignment: .trailing).background(Color.clear)


            }).listRowPlatterColor(Color.blue).frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, alignment: .leading).cornerRadius(10)

        })
    }
}