Swift iOS中如何将指定JSON按日期分组展示带分区的TableView
Swift iOS 实现按日期分组的TableView分区展示
需求说明
给定如下JSON数据:
[ { "Date": "2023-10-12 15: 50: 45+0000", "Text": "Description", "Title": "Recommendation" }, { "Date": "2023-10-13 15: 50: 45+0000", "Text": "Description", "Title": "Recommendation" }, { "Date": "2023-10-14 15: 50: 45+0000", "Text": "Description", "Title": "Title" }, { "Date": "2023-10-12 15: 50: 45+0000", "Text": "Description", "Title": "Recommendation" } ]
需要完成以下任务:
- 创建匹配JSON结构的数据模型
- 实现TableView分区展示,分区标题为同一天的日期
- 单元格内展示
Title和Description内容
现有代码片段如下,需补充按日期分组的逻辑:
struct Elements: Codable { let date, text, title: String } var allDates = [Date]() func formattedModel(model: [Elements]) { for data in model { allDates(data.date) } // Here in allDates we have list of all dates // Now here we need to create date section list of data. }
完整解决方案
1. 修复数据模型与日期解析工具
首先修正模型的Codable键映射,确保和JSON字段匹配,同时封装日期解析工具:
import Foundation // 修正数据模型,匹配JSON的键名 struct Element: Codable { let date: String let text: String let title: String // 自定义键映射,适配JSON的大写开头字段 enum CodingKeys: String, CodingKey { case date = "Date" case text = "Text" case title = "Title" } } // 日期格式化单例,统一处理日期解析和格式转换 class DateFormatterManager { static let shared = DateFormatterManager() private let inputFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd HH: mm: ssZ" formatter.timeZone = TimeZone(identifier: "UTC") return formatter }() private let sectionFormatter: DateFormatter = { let formatter = DateFormatter() formatter.dateFormat = "yyyy-MM-dd" formatter.timeZone = TimeZone.current return formatter }() // 将字符串日期转为Date对象 func date(from string: String) -> Date? { return inputFormatter.date(from: string) } // 获取用于分区标题的日期字符串(仅年月日) func sectionTitle(from date: Date) -> String { return sectionFormatter.string(from: date) } // 生成用于分组的日期键(确保同一天的键相同) func dayGroupKey(from date: Date) -> String { return sectionFormatter.string(from: date) } }
2. 实现按日期分组的核心逻辑
定义分区数据结构,完成分组和排序:
// 分区数据模型:存储分区标题和对应的数据列表 struct DateSection { let title: String let elements: [Element] } // 存储分组后的分区数据 var sections = [DateSection]() func formatAndGroupModels(_ models: [Element]) { let dateManager = DateFormatterManager.shared // 1. 按日期分组:以日期字符串为键,存储对应元素列表 var dateGroups = [String: [Element]]() for element in models { guard let date = dateManager.date(from: element.date) else { continue } let groupKey = dateManager.dayGroupKey(from: date) dateGroups[groupKey, default: []].append(element) } // 2. 将分组转为有序的分区列表(按日期升序排列) let sortedGroupKeys = dateGroups.keys.sorted() sections = sortedGroupKeys.map { key in DateSection(title: key, elements: dateGroups[key] ?? []) } }
3. TableView数据源实现
在ViewController中实现TableView的数据源方法,使用分组后的sections数据:
// MARK: - UITableViewDataSource extension YourViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return sections.count } func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { return sections[section].title } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return sections[section].elements.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID", for: indexPath) let element = sections[indexPath.section].elements[indexPath.row] // 配置单元格内容 cell.textLabel?.text = element.title cell.detailTextLabel?.text = element.text return cell } }
关键注意点
- 日期解析时必须匹配JSON的日期格式和时区,避免解析失败
- 分组时使用仅包含年月日的字符串作为键,确保同一天的元素被分到同一组
- 对分组键进行排序,保证分区按日期顺序展示
内容的提问来源于stack exchange,提问作者user22733877
相关产品推荐
相关产品推荐

