复杂的tableView排序

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

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 &quot;&quot; }
        return DateFormatter.stringDate.string(from: text)
    }
}

extension DateFormatter {
    static let stringDate: DateFormatter = {
        let formatterDate = DateFormatter()
        formatterDate.dateFormat = &quot;MMM d, h:mm a&quot;
        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 &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:

func sortByDate() {
    sections.removeAll()
    let dates = cells.reduce(into: Set&lt;Date&gt;()) { 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]) -&gt; [SectionContent] {
        var sorted = [SectionContent]()
        sorted = unsorted.sorted(by: { $0.sectionDate &lt; $1.sectionDate})
        sorted.enumerated().forEach { index,section in
            sorted[index].sectionContent = section.sectionContent.sorted(by: { $0.cellDate ?? Date() &lt; $1.cellDate ?? Date()})
        }
        return sorted
    }
    
    
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
        return sortedContent(unsorted: sections).count
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -&gt; String? {
        let _section = sortedContent(unsorted: sections)[section]
        return _section.sectionDate.formatted()
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -&gt; 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() -&gt; [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 &lt; $1.sectionDate }

then sort the contents like this

//sort the contents
for index in 0..&lt;sections.count {
    sections[index].sectionContent.sort { $0.cellDate ?? .now &lt; $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] //&lt;--- must be var not let
}

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:

确定