【发布时间】:2020-06-04 08:03:35
【问题描述】:
我正在尝试获取一组项目(结构)并使用 SwiftUI 在分组表视图中显示它们。
我的(简化的)模型如下所示:
struct CheckIn: Identifiable {
...
let id = UUID()
let date = Date().atMidnight // removes the time component
var completed: Bool
...
}
class Store: ObservableObject {
@Published var checkIns = [...] {
didSet { persist() }
}
}
在列表中显示签到之前,我想按日期对它们进行分组。所以我有另一个模型:
struct DailyCheckIns {
let date: Date
let checkIns: [CheckIn]
}
// and a function to group the check-ins array:
func groupByDate(_ checkIns: [CheckIn]) -> [DailyCheckIns] {...}
视图是我遇到问题的地方。下面的版本有效,但数据没有明显分组。 “工作”是指数据被传递到CheckInView,它可以更新其签入,然后正确反映在商店和 UI 中。
struct ContentView: View {
@EnvironmentObject var store: Store
var body: some View {
NavigationView {
List {
ForEach(store.checkIns.indices) { idx in
CheckInView(checkIn: self.$store.checkIns[idx]) // checkIn is a @Binding
}
}
.navigationBarTitle("Check Ins")
}
}
}
下一个版本是我对数据进行分组的尝试。使用这种方法,我必须将CheckInView 的checkIn 属性从@Binding 更改为@State。分组工作并显示数据,但是当签入完成被切换时,模型会更新,但 UI 不会。
struct ContentView: View {
@EnvironmentObject var store: Store
var body: some View {
NavigationView {
List {
ForEach(groupByDate(store.checkIns), id: \.date) { daily in
Section(header: Text(dateFormatter.string(from: daily.date))) {
ForEach(daily.checkIns, id: \.id) { checkIn in
CheckInView(checkIn: checkIn) // I can't use a binding here, so in this version I need to make checkIn a @State.
}
}
}
}
.navigationBarTitle("Check Ins")
}
}
}
目前我没有CheckInView直接修改签到。相反,它将更新发布到商店,商店更新模型:
struct CheckInView: View {
@Binding var checkIn: CheckIn
@EnvironmentObject var store: Store
var body: some View {
HStack {
Button(action: {
self.store.update(checkIn: self.checkIn, with: true)
}) {
Image(systemName: "...")
.font(.largeTitle)
.foregroundColor(checkIn.completed ? .gray : .red)
}
.buttonStyle(BorderlessButtonStyle())
...
所以问题是:如何保持列表分组并保持绑定在视图层次结构中一直有效?
【问题讨论】:
-
您是否尝试将修饰符 .listStyle(GroupedListStyle()) 添加到您的列表中?
-
抱歉,我在深夜打字,弄乱了我的术语。我不是指表格视图的样式,只是数据应该按日期分组。
标签: ios swift swiftui swiftui-list