Ios SwiftUI中的分组列表数据,以分区显示
我试图获取一个项目数组(结构),并使用SwiftUI在分组表视图中显示它们 我的(简化)模型如下所示:Ios SwiftUI中的分组列表数据,以分区显示,ios,swift,swiftui,swiftui-list,Ios,Swift,Swiftui,Swiftui List,我试图获取一个项目数组(结构),并使用SwiftUI在分组表视图中显示它们 我的(简化)模型如下所示: struct签入:可识别{ ... 设id=UUID() 让date=date()。在午夜//删除时间组件 完成变量:Bool ... } 类存储:observeObject{ @已发布的var签入=[…]{ didSet{persist()} } } 在列表中显示签入之前,我想按日期对它们进行分组。所以我有另一个模型: struct DailyCheckIns{ 日期:日期 让我们签入:[
struct签入:可识别{
...
设id=UUID()
让date=date()。在午夜//删除时间组件
完成变量:Bool
...
}
类存储:observeObject{
@已发布的var签入=[…]{
didSet{persist()}
}
}
在列表中显示签入之前,我想按日期对它们进行分组。所以我有另一个模型:
struct DailyCheckIns{
日期:日期
让我们签入:[签入]
}
//以及一个将签入数组分组的函数:
func groupByDate(ucheckins:[CheckIn])->[DailyCheckIns]{…}
这就是我的问题所在。下面的版本有效,但数据没有明显分组。所谓“工作”,我的意思是数据被传递到CheckInView
,它可以更新其签入,然后正确地反映在存储和UI中
struct ContentView:View{
@环境对象变量存储:存储
var body:一些观点{
导航视图{
名单{
ForEach(store.checkIns.index){idx-in
CheckInView(checkIn:self.$store.checkIns[idx])//签入是一个@Binding
}
}
.navigationBarTitle(“签入”)
}
}
}
下一个版本是我对数据分组的尝试。使用这种方法,我必须将CheckInView
的checkIn
属性从@Binding
更改为@State
。分组工作,数据显示,但当切换签入完成时,模型更新,但UI不更新
struct ContentView:View{
@环境对象变量存储:存储
var body:一些观点{
导航视图{
名单{
ForEach(groupByDate(store.checkIns),id:\.date){daily in
节(标题:文本(dateFormatter.string(from:daily.date))){
ForEach(daily.checkIns,id:\.id){checkIn
CheckInView(checkIn:checkIn)//我不能在这里使用绑定,所以在这个版本中,我需要在@State中进行签入。
}
}
}
}
.navigationBarTitle(“签入”)
}
}
}
目前,我没有直接修改签入的CheckInView
。相反,它会向存储发布更新,存储会更新模型:
struct CheckInView:视图{
@绑定var签入:签入
@环境对象变量存储:存储
var body:一些观点{
HStack{
按钮(操作:{
self.store.update(签入:self.checkIn,with:true)
}) {
图像(系统名称:“…”)
.font(.largeTitle)
.foregroundColor(签入.已完成?.gray:红色)
}
.buttonStyle(无边框buttonStyle())
...
因此,问题是:如何将列表分组,并使绑定在视图层次结构中一直工作?我已经想出了如何做到这一点。我不知道这是否是最优雅的解决方案。在我看来,它确实不优雅,但我想不出其他方法可以做到这一点 在我发布的代码中,
DailyCheckIns
是一个用于分组签入的中间模型。函数groupByDate
获取一个CheckIn
s数组,并将其转换为DailyCheckIn
s进行显示。问题在于DailyCheckIn
基本上保存了stor中数据的副本e、 所以我不能用它来创建从它到存储的绑定
我找到的解决方法是使用DailyCheckIn
s来创建节和每个节中的行数,但是当涉及到创建需要绑定到存储的视图时,我直接使用存储的数据。为此,我必须更改DailyCheckIn
s(和groupByDate
)要跟踪商店属性中每个签入的索引,请执行以下操作:
typealias CheckInWithIndex=(Int,CheckIn)
结构DailyCheckIns{
日期:日期
var签入:[签入索引]
func追加(ci:CheckInWithIndex)->DailyCheckIns{
DailyCheckIns(日期:日期,签入:签入+[ci])
}
}
private func groupByDate(ucheckins:[CheckIn])->[DailyCheckIn]{…}
结构ContentView:View{
@环境对象变量存储:存储
var body:一些观点{
导航视图{
名单{
ForEach(groupByDate(store.checkIns),id:\.date){daily in
节(标题:文本(dateFormatter.string(from:daily.date))){
ForEach(daily.checkIns,id:\.id){checkInWithIndex-in
CheckInView(签入:self.$store.checkIns[checkInWithIndex.0])
}
}
}
}
.navigationBarTitle(“签入”)
}
}
}
希望这对某人有所帮助。但是,我也希望有人能找到更好的方法来解决这种情况。我已经找到了解决方法。我不知道这是否是最优雅的解决方案。我觉得这看起来并不优雅,但我想不出其他方法
在我发布的代码中,DailyCheckIns
是一个用于分组签入的中间模型。函数groupByDate
获取一个CheckIn
s数组,并将其转换为DailyCheckIn
s进行显示。问题在于DailyCheckIn
基本上保存了stor中数据的副本e、 所以我不能用它来创建从它到存储的绑定
我找到的解决方法是使用DailyCheckIn
s来创建节和每个节中的行数,但是当涉及到创建需要绑定到存储的视图时,我直接使用存储的数据。为此,我必须更改DailyCheckIn
s(和groupByDate
)要跟踪商店属性中每个签入的索引,请执行以下操作:
typealias CheckInWithIndex=(Int,Chec