I have a dictionary that contains a key/value pair of a Date that contains an array of my custom object Meals grouped together by the same dates.
Meal Object:
Create a struct for the sections
struct Section {
let date : Date
let meals : [Meal]
}
and map the grouped dictionary to an array of Section
var sections = [Section]()
let sortedDates = self.grouped.keys.sorted(>)
sections = sortedDates.map{Section(date: $0, meals: self.grouped[$0]!)}
You could add a date formatter to display the Date
instance more meaningful.
The table view data source methods are
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]
...
Note:
Consider to use less optionals and a struct rather than a NSObject
subclass. Unlike NSCoding
Codable
does not require to conform to NSObjectProtocol
. And never declare properties as implicit unwrapped optional.
In your datamodel, you take the dictionary that you have with one day per entry, take the keys as an array, and sort the array.
Your tableview has as many sections as that array has entries. You create the title of each section from the date. For every section, you take the array of meals from the dictionary, so each section has a different number of rows, and the data from eac row is taken from one row of the arrays.
For example, to get the data for section 3, row 5, you take the date from your array of dates at index 3, you lookup the date in the dictionary and get an array of meals, and the meal at index 5 provides the data.