【发布时间】:2023-02-06 03:28:37
【问题描述】:
如果这是一个简单的问题,通常是 swiftui 新手的警告和道歉。
我有一个视图,其中有一个日期选择器,以及两个用于增加/减少日期的箭头。更新此日期后,我试图从数据库中筛选出与当前显示日期匹配的“会话”列表。
我有一个 filteredSessions 变量,它对数据库中的所有“会话”应用过滤器。但是,每次更改日期时,我似乎都没有刷新该过滤器。
我将要使用的日期存储为视图中的“@State”对象。我认为这会在该字段更改时触发视图更新?但是我运行了调试器,发现“filteredSessions”变量只被调用一次,而不是在日期更改时(通过选择器或按钮)。
我在这里缺少什么吗?我是否需要一种特殊的方法来将此日期值“绑定”到列表,因为显示器不直接使用它?
下面的代码。谢谢
import SwiftUI
struct TrainingSessionListView: View {
@StateObject var viewModel = TrainingSessionsViewModel()
@State private var displayDate: Date = Date.now
@State private var presentAddSessionSheet = false
private var dateManager = DateManager()
private let oneDay : Double = 86400
private var addButton : some View {
Button(action: { self.presentAddSessionSheet.toggle() }) {
Image(systemName: "plus")
}
}
private var decreaseDayButton : some View {
Button(action: { self.decreaseDay() }) {
Image(systemName: "chevron.left")
}
}
private var increaseDayButton : some View {
Button(action: { self.increaseDay() }) {
Image(systemName: "chevron.right")
}
}
private func sessionListItem(session: TrainingSession) -> some View {
NavigationLink(destination: TrainingSessionDetailView(session: session)) {
VStack(alignment: .leading) {
Text(session.title)
.bold()
Text("\(session.startTime) - \(session.endTime)")
}
}
}
private func increaseDay() {
self.displayDate.addTimeInterval(oneDay)
}
private func decreaseDay() {
self.displayDate.addTimeInterval(-oneDay)
}
var body: some View {
NavigationView {
VStack {
HStack {
Spacer()
decreaseDayButton
Spacer()
DatePicker("", selection: $displayDate, displayedComponents: .date)
.labelsHidden()
Spacer()
increaseDayButton
Spacer()
}
.padding(EdgeInsets(top: 25, leading: 0, bottom: 0, trailing: 0))
Spacer()
ForEach(filteredSessions) { session in
sessionListItem(session: session)
}
Spacer()
}
.navigationTitle("Training Sessions")
.navigationBarTitleDisplayMode(.inline)
.navigationBarItems(trailing: addButton)
.sheet(isPresented: $presentAddSessionSheet) {
TrainingSessionEditView()
}
}
}
var filteredSessions : [TrainingSession] {
print("filteredSessions called")
return viewModel.sessions.filter { $0.date == dateManager.dateToStr(date: displayDate) }
}
}
struct TrainingSessionListView_Previews: PreviewProvider {
static var previews: some View {
TrainingSessionListView()
}
}
【问题讨论】:
-
您可能想在分配
filteredSessions的地方引入另一个 @State 变量,即创建一个返回过滤集的函数并为其分配一个相应的 @State 变量。