按字典中的日期对表视图进行分区
Sectioning a tableview by dates from a dictionary
我有一个字典,其中包含 key/value 对日期,其中包含按相同日期分组的自定义对象 Meals 的数组。
用餐对象:
class Meal: NSObject, Codable {
var id: String?
var foodname: String?
var quantity: Float!
var brandName: String?
var quantityType: String?
var calories: Float!
var date: Date?
}
在我的 TableView 中:
var grouped = Dictionary<Date, [Meal]>()
var listOfAllMeals = [Meal]() //already populated
self.grouped = Dictionary(grouping: self.listOfAllMeals.sorted(by: { ([=11=].date ?? nilDate) < (.date ?? nilDate) }),
by: { calendar.startOfDay(for: [=11=].date ?? nilDate) })
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return grouped.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return Array(grouped.keys)[section] as! String //this throws a thread error
}
这允许用户一天多次上传餐点以供将来查看,现在我想在 TableView 中显示按日期划分的餐点并已按最新排序。我该如何实现?
在您的数据模型中,您使用每个条目一天的字典,将键作为一个数组,并对数组进行排序。
您的表视图的部分数量与该数组的条目数量一样多。您根据日期创建每个部分的标题。对于每个部分,您都从字典中获取膳食数组,因此每个部分都有不同的行数,并且每一行的数据都取自数组的一行。
例如,要获取第 3 节第 5 行的数据,您可以从索引 3 处的日期数组中获取日期,然后在字典中查找日期并获取膳食数组,而膳食位于索引 5 提供数据。
为节创建一个结构
struct Section {
let date : Date
let meals : [Meal]
}
并将分组字典映射到 Section
的数组
var sections = [Section]()
let sortedDates = self.grouped.keys.sorted(>)
sections = sortedDates.map{Section(date: [=11=], meals: self.grouped[[=11=]]!)}
您可以添加日期格式化程序以显示更有意义的 Date
实例。
table查看数据源的方法有
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].date.description
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].meals.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "foodCell", for: indexPath)
let meal = sections[indexPath.section].meals[indexPath.row]
...
注:
考虑使用较少的可选值和结构而不是 NSObject
子类。不像NSCoding
Codable
不需要符合NSObjectProtocol
。 从不 将属性声明为隐式解包可选。
我有一个字典,其中包含 key/value 对日期,其中包含按相同日期分组的自定义对象 Meals 的数组。
用餐对象:
class Meal: NSObject, Codable {
var id: String?
var foodname: String?
var quantity: Float!
var brandName: String?
var quantityType: String?
var calories: Float!
var date: Date?
}
在我的 TableView 中:
var grouped = Dictionary<Date, [Meal]>()
var listOfAllMeals = [Meal]() //already populated
self.grouped = Dictionary(grouping: self.listOfAllMeals.sorted(by: { ([=11=].date ?? nilDate) < (.date ?? nilDate) }),
by: { calendar.startOfDay(for: [=11=].date ?? nilDate) })
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return grouped.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return Array(grouped.keys)[section] as! String //this throws a thread error
}
这允许用户一天多次上传餐点以供将来查看,现在我想在 TableView 中显示按日期划分的餐点并已按最新排序。我该如何实现?
在您的数据模型中,您使用每个条目一天的字典,将键作为一个数组,并对数组进行排序。
您的表视图的部分数量与该数组的条目数量一样多。您根据日期创建每个部分的标题。对于每个部分,您都从字典中获取膳食数组,因此每个部分都有不同的行数,并且每一行的数据都取自数组的一行。
例如,要获取第 3 节第 5 行的数据,您可以从索引 3 处的日期数组中获取日期,然后在字典中查找日期并获取膳食数组,而膳食位于索引 5 提供数据。
为节创建一个结构
struct Section {
let date : Date
let meals : [Meal]
}
并将分组字典映射到 Section
var sections = [Section]()
let sortedDates = self.grouped.keys.sorted(>)
sections = sortedDates.map{Section(date: [=11=], meals: self.grouped[[=11=]]!)}
您可以添加日期格式化程序以显示更有意义的 Date
实例。
table查看数据源的方法有
override func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return sections[section].date.description
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sections[section].meals.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "foodCell", for: indexPath)
let meal = sections[indexPath.section].meals[indexPath.row]
...
注:
考虑使用较少的可选值和结构而不是 NSObject
子类。不像NSCoding
Codable
不需要符合NSObjectProtocol
。 从不 将属性声明为隐式解包可选。