You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS:基于日期对Person数组排序并实现UICollectionView分组

解决Person数组按日期分组排序并适配UICollectionView分组的问题

我来帮你一步步搞定这个需求!核心思路是先按日期天粒度排序Person数组,再按天分组,最后将分组数据适配到UICollectionView的section结构中。以下是具体实现步骤:

1. 基础准备:定义相关结构体(如果还没做的话)

首先假设你的Person结构体是这样的(根据实际情况调整字段):

struct Person {
    let inscriptionDate: TimeInterval // 时间戳(注意是秒级还是毫秒级,毫秒的话后续要除以1000)
    // 其他字段:name, age...
}

我们还需要一个Section结构体来存储UICollectionView分组的头部标题和对应的数据:

struct Section {
    let dateTitle: String // 格式为dd/mm/yyyy的日期标题
    let people: [Person]  // 该日期下的Person数组
}

2. 按日期天粒度排序Person数组

你提到的NSCalendar.compareDate在Swift中可以用Calendar.current.compare(_:to:toGranularity:)替代,它能帮我们忽略时分秒,只比较日期的天维度。

// 先把时间戳转成Date对象(如果是毫秒级时间戳,记得除以1000)
func convertTimestampToDate(_ timestamp: TimeInterval) -> Date {
    return Date(timeIntervalSince1970: timestamp)
}

// 对Person数组按日期升序排序(旧日期在前,新日期在后)
let calendar = Calendar.current
let sortedPeople: [Person] = yourOriginalPersonArray.sorted { person1, person2 in
    let date1 = convertTimestampToDate(person1.inscriptionDate)
    let date2 = convertTimestampToDate(person2.inscriptionDate)
    
    // 比较两个日期的天粒度,判断date1是否在date2之前
    return calendar.compare(date1, to: date2, toGranularity: .day) == .orderedAscending
}

3. 按日期天分组生成Section数组

排序完成后,我们需要把同一天的Person归为一组,并生成带日期标题的Section:

// 获取某个日期的当天起始时刻(比如2024-05-20 00:00:00),用作分组的唯一标识
func getStartOfDay(for date: Date) -> Date {
    return calendar.startOfDay(for: date)
}

// 按当天起始日期分组Person数组
let groupedPeopleDict = Dictionary(grouping: sortedPeople) { person in
    let date = convertTimestampToDate(person.inscriptionDate)
    return getStartOfDay(for: date)
}

// 将分组字典转成有序的Section数组
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/mm/yyyy" // 注意:如果是月份请用MM,小写mm是分钟!
dateFormatter.locale = Locale(identifier: "en_US_POSIX") // 避免区域设置影响格式

let sections: [Section] = groupedPeopleDict
    .sorted { $0.key < $1.key } // 按日期顺序排序分组
    .map { (startDate, people) in
        Section(
            dateTitle: dateFormatter.string(from: startDate),
            people: people
        )
    }

4. 适配UICollectionView数据源

现在sections数组已经完全适配UICollectionView的分组需求,直接在数据源方法中使用即可:

// 返回分组数量
func numberOfSections(in collectionView: UICollectionView) -> Int {
    return sections.count
}

// 返回每组的Item数量
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return sections[section].people.count
}

// 返回分组头部视图
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    guard kind == UICollectionView.elementKindSectionHeader else {
        return UICollectionReusableView()
    }
    
    let header = collectionView.dequeueReusableSupplementaryView(
        ofKind: kind,
        withReuseIdentifier: "YourHeaderReuseID",
        for: indexPath
    ) as! YourCustomHeaderView
    
    header.titleLabel.text = sections[indexPath.section].dateTitle
    return header
}

关键细节提醒

  • 如果你的inscriptionDate是毫秒级时间戳,记得在convertTimestampToDate方法中除以1000:Date(timeIntervalSince1970: timestamp / 1000)
  • 日期格式中的mm代表分钟,如果你需要的是月份,请改成MM(比如dd/MM/yyyy)
  • 排序方向可以通过修改.orderedAscending为.orderedDescending来切换(新日期在前)

内容的提问来源于stack exchange,提问作者Ne AS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:26:33