首页 > 解决方案 > 如何在 SwiftUI 中以交互方式按年份过滤日期列表

问题描述

我有一个来自核心数据实体的 NSManagedObject 子类MyEntity

@NSManaged public var name: String
@NSManaged public var date: Date

和一份清单。我准备了一个 ScrollView,其中包含可用于过滤列表的按钮(?)

func groupYears(fetchedResults: FetchedResults<MyEntity>) -> [Int] {
    var result = [Int]()
    for fetchedResult in fetchedResults {
        let component = Calendar.current.dateComponents([.year], from: fetchedResult.date)
        if !result.contains(component.year!) {
            result.append(component.year!)
        }
    }
    return result
}
@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \MyEntity.date, ascending: true)]) var fetchedResults: FetchedResults<MyEntity>
VStack {
    ScrollView(.horizontal, showsIndicators: false) {
        HStack(spacing: 15) {
            Button(action: {}) { Text("all") }
            ForEach(groupYears(fetchedResults: fetchedResults), id: \.self) { year in
                Button(action: {}) { Text(String(year)) }
            }
        }
    }
    List(fetchedResults, id: \.self) { result in
        VStack(alignment: .leading) {
            Text(result.name)
            Text(dateFormatter.string(from: result.date))
        }
    }
}

我想单击一个按钮,列表应动态过滤相关年份。

如何动态过滤列表?

标签: iosswiftcore-dataswiftui

解决方案


您可以添加一个属性来存储您选择的年份:

@State var selectedYear: Int?
Button(action: {
    self.selectedYear = nil
}) { 
    Text("all") 
}
ForEach(groupYears(fetchedResults: fetchedResults), id: \.self) { year in
    Button(action: {
        self.selectedYear = year
    }) { 
        Text(String(year)) 
    }
}

然后按此选定年份过滤列表:

ForEach(fetchedResults.filter({ isDateInSelectedYear($0.date) }), id: \.self) { ...
func isDateInSelectedYear(_ date: Date) -> Bool {
    if selectedYear == nil {
        return true
    }
    return Calendar.current.component(.year, from: date) == selectedYear
}

推荐阅读