skip to Main Content

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)?

enter image description here

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) } }

2

Answers


  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

    Login or Signup to reply.
  2. 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
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search