英文:
Complex sorting in tableView
问题
我有两个数组:
var sections: [SectionContent] = []
var cells: [CellContent] = []
这两个数组中的一个嵌套在另一个数组中:
struct SectionContent {
let sectionDate: Date
let sectionContent: [CellContent]
}
struct CellContent {
let cellDate: Date?
var formattedDate: String {
guard let text = cellDate else { return "" }
return DateFormatter.stringDate.string(from: text)
}
}
extension DateFormatter {
static let stringDate: DateFormatter = {
let formatterDate = DateFormatter()
formatterDate.dateFormat = "MMM d, h:mm a"
return formatterDate
}()
}
'sections' 数组在 tableView 中显示日期作为部分标题。
'cells' 数组显示分配给该日期的相应数据。
日期是在单独的视图控制器中设置的,从该视图控制器执行 unwindSegue 返回到第一个视图控制器。
我成功通过在 unwindSegue 中包含以下代码对部分按日期进行排序:
sections.sort { $0.sectionDate < $1.sectionDate }
问题:在我的配置下,如何按照相应的时间对一个部分内的单元格进行排序(较早的时间在顶部,较晚的时间在底部)?
英文:
I have two arrays:
var sections: [SectionContent] = []
var cells: [CellContent] = []
Of those two arrays, one is nested inside the other one:
struct SectionContent {
let sectionDate: Date
let sectionContent: [CellContent]
}
struct CellContent {
let cellDate: Date?
var formattedDate: String {
guard let text = cellDate else { return "" }
return DateFormatter.stringDate.string(from: text)
}
}
extension DateFormatter {
static let stringDate: DateFormatter = {
let formatterDate = DateFormatter()
formatterDate.dateFormat = "MMM d, h:mm a"
return formatterDate
}()
}
The 'sections' array displays the date as the section header in tableView.
The 'cells' array displays the respective data assigned to that date.
The date is set in a separate viewController from which I do the unwindSegue to the first viewController.
I managed to sort the sections by date thru including this code inside of the unwindSegue:
sections.sort { $0.sectionDate < $1.sectionDate }
Question: Given my configuration, how do I sort cells within one section by the corresponding time (earlier time at the top and later at the bottom)?
Edit: This is how I construct the Section:
func sortByDate() {
sections.removeAll()
let dates = cells.reduce(into: Set<Date>()) { result, cells in
let date = Calendar.current.startOfDay(for: cells.cellDate!)
result.insert(date) }
for date in dates {
let dateComp = Calendar.current.dateComponents([.year, .month, .day], from: date)
var sortedContent: [CellContent] = []
cells.forEach { cells in
let contComp = Calendar.current.dateComponents([.year, .month, .day], from: cells.cellDate!)
if contComp == dateComp {
sortedContent.append(cells) } }
let newSection = SectionContent(sectionDate: date, sectionContent: sortedContent)
sections.append(newSection) } }
答案1
得分: 1
class ViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {
var sections: [SectionContent] = SectionContent.demo()
// just give unsorted/sorted sections to this function and it will return sorted section
func sortedContent(unsorted:[SectionContent]) -> [SectionContent] {
var sorted = [SectionContent]()
sorted = unsorted.sorted(by: { $0.sectionDate < $1.sectionDate})
sorted.enumerated().forEach { index,section in
sorted[index].sectionContent = section.sectionContent.sorted(by: { $0.cellDate ?? Date() < $1.cellDate ?? Date()})
}
return sorted
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sortedContent(unsorted: sections).count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let _section = sortedContent(unsorted: sections)[section]
return _section.sectionDate.formatted()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let section = sortedContent(unsorted: sections)[indexPath.section]
let row = section.sectionContent[indexPath.row]
}
}
struct SectionContent {
let sectionDate: Date
var sectionContent: [CellContent]
static func demo() -> [SectionContent] {
return [SectionContent(sectionDate: Date().addingTimeInterval(-46000),
sectionContent: [CellContent(cellDate: Date().addingTimeInterval(4000)),
CellContent(cellDate: Date().addingTimeInterval(3000)),
CellContent(cellDate: Date().addingTimeInterval(1000)),
CellContent(cellDate: Date().addingTimeInterval(60))]),
SectionContent(sectionDate: Date().addingTimeInterval(-76000),
sectionContent: [CellContent(cellDate: Date())]),
SectionContent(sectionDate: Date().addingTimeInterval(-6000),
sectionContent: [CellContent(cellDate: Date())]),
SectionContent(sectionDate: Date().addingTimeInterval(-50),
sectionContent: [CellContent(cellDate: Date())])]
}
}
Just give unsorted/sorted sections to this function and it will return sorted section
英文:
class ViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {
var sections: [SectionContent] = SectionContent.demo()
// just give unsorted/sorted sections to this function and it will return sorted section
func sortedContent(unsorted:[SectionContent]) -> [SectionContent] {
var sorted = [SectionContent]()
sorted = unsorted.sorted(by: { $0.sectionDate < $1.sectionDate})
sorted.enumerated().forEach { index,section in
sorted[index].sectionContent = section.sectionContent.sorted(by: { $0.cellDate ?? Date() < $1.cellDate ?? Date()})
}
return sorted
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sortedContent(unsorted: sections).count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
let _section = sortedContent(unsorted: sections)[section]
return _section.sectionDate.formatted()
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let section = sortedContent(unsorted: sections)[indexPath.section]
let row = section.sectionContent[indexPath.row]
}
}
struct SectionContent {
let sectionDate: Date
var sectionContent: [CellContent]
static func demo() -> [SectionContent] {
return [SectionContent(sectionDate: Date().addingTimeInterval(-46000),
sectionContent: [CellContent(cellDate: Date().addingTimeInterval(4000)),
CellContent(cellDate: Date().addingTimeInterval(3000)),
CellContent(cellDate: Date().addingTimeInterval(1000)),
CellContent(cellDate: Date().addingTimeInterval(60))]),
SectionContent(sectionDate: Date().addingTimeInterval(-76000),
sectionContent: [CellContent(cellDate: Date())]),
SectionContent(sectionDate: Date().addingTimeInterval(-6000),
sectionContent: [CellContent(cellDate: Date())]),
SectionContent(sectionDate: Date().addingTimeInterval(-50),
sectionContent: [CellContent(cellDate: Date())])]
}
}
Just give unsorted/sorted sections to this function and it will return sorted section
答案2
得分: 0
sort the sections as you're already doing it
//排序部分
sections.sort { $0.sectionDate < $1.sectionDate }
then sort the contents like this
//排序内容
for index in 0..<sections.count {
sections[index].sectionContent.sort { $0.cellDate ?? .now < $1.cellDate ?? .now }
}
note that you must change sectionContent
to a var for the second sort to work
请注意,必须将 sectionContent
更改为变量(var),以使第二个排序有效
结构体 SectionContent {
let sectionDate: Date
var sectionContent: [CellContent] // <--- 必须为 var,而不是 let
}
英文:
sort the sections as you're already doing it
//sort the sections
sections.sort { $0.sectionDate < $1.sectionDate }
then sort the contents like this
//sort the contents
for index in 0..<sections.count {
sections[index].sectionContent.sort { $0.cellDate ?? .now < $1.cellDate ?? .now }
}
note that you must change sectionContent
to a var for the second sort to work
struct SectionContent {
let sectionDate: Date
var sectionContent: [CellContent] //<--- must be var not let
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论