How to update filtered list in swiftui, when the value in the filter is changed?
08:51 02 Feb 2023

Usual caveat of being new to swiftui and apologies is this is a simple question.

I have a view where I have a date picker, as well as two arrows to increase/decrease the day. When this date is update, I am trying to filter a list of 'sessions' from the database which match the currently displayed date.

I have a filteredSessions variable which applies a filter to all 'sessions' from the database. However I do not seem to have that filter refreshed each time the date is changed.

I have the date to be used stored as a "@State" object in the view. I thought this would trigger the view to update whenever that field is changed? However I have run the debugger and found the 'filteredSessions' variable is only called once, and not when the date is changed (either by the picker or the buttons).

Is there something I'm missing here? Do I need a special way to 'bind' this date value to the list because it isn't directly used by the display?

Code below. Thanks

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()
    }
}
ios swift swiftui filter