复杂的tableView排序

huangapple go评论97阅读模式
英文:

Complex sorting in tableView

问题

我有两个数组:

  1. var sections: [SectionContent] = []
  2. var cells: [CellContent] = []

这两个数组中的一个嵌套在另一个数组中:

  1. struct SectionContent {
  2. let sectionDate: Date
  3. let sectionContent: [CellContent]
  4. }
  5. struct CellContent {
  6. let cellDate: Date?
  7. var formattedDate: String {
  8. guard let text = cellDate else { return "" }
  9. return DateFormatter.stringDate.string(from: text)
  10. }
  11. }
  12. extension DateFormatter {
  13. static let stringDate: DateFormatter = {
  14. let formatterDate = DateFormatter()
  15. formatterDate.dateFormat = "MMM d, h:mm a"
  16. return formatterDate
  17. }()
  18. }

'sections' 数组在 tableView 中显示日期作为部分标题。

'cells' 数组显示分配给该日期的相应数据。

日期是在单独的视图控制器中设置的,从该视图控制器执行 unwindSegue 返回到第一个视图控制器。

我成功通过在 unwindSegue 中包含以下代码对部分按日期进行排序:

  1. sections.sort { $0.sectionDate < $1.sectionDate }

问题:在我的配置下,如何按照相应的时间对一个部分内的单元格进行排序(较早的时间在顶部,较晚的时间在底部)?

英文:

I have two arrays:

  1. var sections: [SectionContent] = []
  2. var cells: [CellContent] = []

Of those two arrays, one is nested inside the other one:

  1. struct SectionContent {
  2. let sectionDate: Date
  3. let sectionContent: [CellContent]
  4. }
  5. struct CellContent {
  6. let cellDate: Date?
  7. var formattedDate: String {
  8. guard let text = cellDate else { return &quot;&quot; }
  9. return DateFormatter.stringDate.string(from: text)
  10. }
  11. }
  12. extension DateFormatter {
  13. static let stringDate: DateFormatter = {
  14. let formatterDate = DateFormatter()
  15. formatterDate.dateFormat = &quot;MMM d, h:mm a&quot;
  16. return formatterDate
  17. }()
  18. }

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:

  1. sections.sort { $0.sectionDate &lt; $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)?

复杂的tableView排序

Edit: This is how I construct the Section:

  1. func sortByDate() {
  2. sections.removeAll()
  3. let dates = cells.reduce(into: Set&lt;Date&gt;()) { result, cells in
  4. let date = Calendar.current.startOfDay(for: cells.cellDate!)
  5. result.insert(date) }
  6. for date in dates {
  7. let dateComp = Calendar.current.dateComponents([.year, .month, .day], from: date)
  8. var sortedContent: [CellContent] = []
  9. cells.forEach { cells in
  10. let contComp = Calendar.current.dateComponents([.year, .month, .day], from: cells.cellDate!)
  11. if contComp == dateComp {
  12. sortedContent.append(cells) } }
  13. let newSection = SectionContent(sectionDate: date, sectionContent: sortedContent)
  14. sections.append(newSection) } }

答案1

得分: 1

class ViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {

  1. var sections: [SectionContent] = SectionContent.demo()
  2. // just give unsorted/sorted sections to this function and it will return sorted section
  3. func sortedContent(unsorted:[SectionContent]) -> [SectionContent] {
  4. var sorted = [SectionContent]()
  5. sorted = unsorted.sorted(by: { $0.sectionDate < $1.sectionDate})
  6. sorted.enumerated().forEach { index,section in
  7. sorted[index].sectionContent = section.sectionContent.sorted(by: { $0.cellDate ?? Date() < $1.cellDate ?? Date()})
  8. }
  9. return sorted
  10. }
  11. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  12. return sortedContent(unsorted: sections).count
  13. }
  14. func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
  15. let _section = sortedContent(unsorted: sections)[section]
  16. return _section.sectionDate.formatted()
  17. }
  18. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  19. let section = sortedContent(unsorted: sections)[indexPath.section]
  20. let row = section.sectionContent[indexPath.row]
  21. }

}

struct SectionContent {

  1. let sectionDate: Date
  2. var sectionContent: [CellContent]
  3. static func demo() -> [SectionContent] {
  4. return [SectionContent(sectionDate: Date().addingTimeInterval(-46000),
  5. sectionContent: [CellContent(cellDate: Date().addingTimeInterval(4000)),
  6. CellContent(cellDate: Date().addingTimeInterval(3000)),
  7. CellContent(cellDate: Date().addingTimeInterval(1000)),
  8. CellContent(cellDate: Date().addingTimeInterval(60))]),
  9. SectionContent(sectionDate: Date().addingTimeInterval(-76000),
  10. sectionContent: [CellContent(cellDate: Date())]),
  11. SectionContent(sectionDate: Date().addingTimeInterval(-6000),
  12. sectionContent: [CellContent(cellDate: Date())]),
  13. SectionContent(sectionDate: Date().addingTimeInterval(-50),
  14. sectionContent: [CellContent(cellDate: Date())])]
  15. }

}

Just give unsorted/sorted sections to this function and it will return sorted section

英文:
  1. class ViewController:UIViewController,UITableViewDataSource,UITableViewDelegate {
  2. var sections: [SectionContent] = SectionContent.demo()
  3. // just give unsorted/sorted sections to this function and it will return sorted section
  4. func sortedContent(unsorted:[SectionContent]) -&gt; [SectionContent] {
  5. var sorted = [SectionContent]()
  6. sorted = unsorted.sorted(by: { $0.sectionDate &lt; $1.sectionDate})
  7. sorted.enumerated().forEach { index,section in
  8. sorted[index].sectionContent = section.sectionContent.sorted(by: { $0.cellDate ?? Date() &lt; $1.cellDate ?? Date()})
  9. }
  10. return sorted
  11. }
  12. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
  13. return sortedContent(unsorted: sections).count
  14. }
  15. func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -&gt; String? {
  16. let _section = sortedContent(unsorted: sections)[section]
  17. return _section.sectionDate.formatted()
  18. }
  19. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; UITableViewCell {
  20. let section = sortedContent(unsorted: sections)[indexPath.section]
  21. let row = section.sectionContent[indexPath.row]
  22. }
  23. }
  24. struct SectionContent {
  25. let sectionDate: Date
  26. var sectionContent: [CellContent]
  27. static func demo() -&gt; [SectionContent] {
  28. return [SectionContent(sectionDate: Date().addingTimeInterval(-46000),
  29. sectionContent: [CellContent(cellDate: Date().addingTimeInterval(4000)),
  30. CellContent(cellDate: Date().addingTimeInterval(3000)),
  31. CellContent(cellDate: Date().addingTimeInterval(1000)),
  32. CellContent(cellDate: Date().addingTimeInterval(60))]),
  33. SectionContent(sectionDate: Date().addingTimeInterval(-76000),
  34. sectionContent: [CellContent(cellDate: Date())]),
  35. SectionContent(sectionDate: Date().addingTimeInterval(-6000),
  36. sectionContent: [CellContent(cellDate: Date())]),
  37. SectionContent(sectionDate: Date().addingTimeInterval(-50),
  38. sectionContent: [CellContent(cellDate: Date())])]
  39. }
  40. }

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

  1. //sort the sections
  2. sections.sort { $0.sectionDate &lt; $1.sectionDate }

then sort the contents like this

  1. //sort the contents
  2. for index in 0..&lt;sections.count {
  3. sections[index].sectionContent.sort { $0.cellDate ?? .now &lt; $1.cellDate ?? .now }
  4. }

note that you must change sectionContent to a var for the second sort to work

  1. struct SectionContent {
  2. let sectionDate: Date
  3. var sectionContent: [CellContent] //&lt;--- must be var not let
  4. }

huangapple
  • 本文由 发表于 2023年5月29日 17:08:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76356017.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定