Что вам нужно сделать, это сгруппировать данные по дате
let grouped: [Data: [Objects]]!
//...
self.result = Array(self.data)
grouped = Dictionary(grouping: result) { (element) -> Date in
return element.date
}
Это создаст словарь, объединяющий все элементы с одинаковым Date
.Теперь вам может потребоваться принять некоторые дополнительные решения, например, вместо этого сгруппировать их только по месяцам и годам.
Получив это, вы в основном получите структуру своей таблицы (разделы - это ключи словаря иданные строк за ключами.
Для убедительности я мог бы также включить ...
sections = grouped.keys.sorted()
, чтобы ускорить доступ к ключам в указанном порядке.
Тогда вам просто нужно применить соответствующие данные к вашему делегату ...
func numberOfSections(in tableView: UITableView) -> Int {
return sections.count
}
// Set the spacing between sections
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return cellSpacingHeight
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return grouped[sections[section]]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let rows = grouped[sections[indexPath.section]]!
let row = rows[indexPath.row]
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"
let stringGivenDate = dateFormatter.string(from: row.date!)
cell.textLabel?.text = "\(stringGivenDate)"
cell.detailTextLabel?.text = "\(row.name!)"
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let date = sections[section]
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"
return dateFormatter.string(from: date)
}
В качестве примечания: DateFormatter
стоит дорого, поэтому вы можете вместо этого сделать это свойство экземпляра
Пример работоспособности ....
//
// ViewController.swift
// QuickTest
//
// Created by Shane Whitehead on 10/2/19.
// Copyright © 2019 Swann Communications. All rights reserved.
//
import UIKit
struct Stuff: CustomDebugStringConvertible {
let date: Date
let name: String
var debugDescription: String {
return "\(date) = \(name)"
}
}
extension Date {
static func random(daysBack: Int)-> Date {
let day = arc4random_uniform(UInt32(daysBack))+1
let hour = arc4random_uniform(23)
let minute = arc4random_uniform(59)
let today = Date(timeIntervalSinceNow: 0)
let calendar = Calendar.current
var offsetComponents = DateComponents()
offsetComponents.day = -Int(day)
offsetComponents.hour = Int(hour)
offsetComponents.minute = Int(minute)
let randomDate = calendar.date(byAdding: offsetComponents, to: today)
return randomDate!
}
var startOfDay: Date {
let calendar = Calendar.current
return calendar.startOfDay(for: self)
}
}
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
let cellSpacingHeight: CGFloat = 5
var grouped: [Date: [Stuff]] = [:]
var sections: [Date] = []
var headerDateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM yyyy"
return dateFormatter
}()
var cellDateFormatter: DateFormatter = {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"
return dateFormatter
}()
override func viewDidLoad() {
super.viewDidLoad()
retreiveData()
tableView.delegate = self
tableView.dataSource = self
tableView.rowHeight = UITableView.automaticDimension
tableView.sectionHeaderHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 44
tableView.estimatedSectionHeaderHeight = 44
tableView.reloadData()
}
func retreiveData() {
var data: [Stuff] = []
for index in 0..<100 {
let stuff = Stuff(date: Date.random(daysBack: 10), name: "\(index)")
data.append(stuff)
}
grouped = Dictionary(grouping: data) { (element) -> Date in
return element.date.startOfDay
}
sections = grouped.keys.sorted()
}
// MARK: - Table View delegate methods
func numberOfSections(in tableView: UITableView) -> Int {
return grouped.count
}
// Set the spacing between sections
// func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
// return cellSpacingHeight
// }
/*func numberOfSections(in tableView: UITableView) -> Int {
return 1
}*/
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return grouped[sections[section]]!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
let rows = grouped[sections[indexPath.section]]!
let row = rows[indexPath.row]
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE - dd.MM.yyyy"
let stringGivenDate = dateFormatter.string(from: row.date)
cell.textLabel?.text = "\(stringGivenDate)"
cell.detailTextLabel?.text = "\(row.name)"
return cell
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let date = sections[section]
return headerDateFormatter.string(from: date)
}
}