列表项未更新
List item is not being updated
所以我有一个 View
和 List
个接受对象的子视图。这些对象来自我的数据管理器中的数组。
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)
})
}
}
这里是GoalWrapper
class
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)
})
}
}
所以我有一个 View
和 List
个接受对象的子视图。这些对象来自我的数据管理器中的数组。
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)
})
}
}
这里是GoalWrapper
class
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)
})
}
}