Ios 按日期对UITableView节进行分组

Ios 按日期对UITableView节进行分组,ios,swift,uitableview,Ios,Swift,Uitableview,我有一个带有标题、开始日期和结束日期的JSON文件。我想在UITableView中按日期对我的分区进行分组,并将每个分组的日期添加为标题。我不确定如何从groupByDate函数中检索数据以填充特定部分。我必须从groupByDate函数创建一个新数组 var eventList: [Event] = [] var eventGroup: [[Event]] = [] func numberOfSections(in tableView: UITableView) ->

我有一个带有标题、开始日期和结束日期的JSON文件。我想在UITableView中按日期对我的分区进行分组,并将每个分组的日期添加为标题。我不确定如何从groupByDate函数中检索数据以填充特定部分。我必须从groupByDate函数创建一个新数组

   var eventList: [Event] = []
   var eventGroup: [[Event]] = []  

func numberOfSections(in tableView: UITableView) -> Int {
    return eventGroup.count
}


 func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
    v.backgroundColor = .darkGray
    return v
}

 func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return 3.0
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyTableCell


        cell.titleLabel.textColor = .red
    }else{
        cell.titleLabel.textColor = .black
    }
    return cell
}
更新 假设的初始数据如下

[
    {
        "title": "Bicycling with Friends",
        "start": "11-01-2018"
    },
    {
        "title": "Yoga",
        "start": "11-01-2018"
    },
    {
        "title": "Yoga",
        "start": "11-02-2018"
    }
]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   return eventGroup[section].count
}

func numberOfSections(in tableView: UITableView) -> Int {
   return eventGroup.count
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let events = eventGroup[section]
    let event = events.first

    return event?.title //Replace with the header title you want
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyTableCell

    let events = eventGroup[indexPath.section]
    let dateRow = events[indexPath.row].start
    let dateRowEnd = events[indexPath.row].end

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

    let myString = formatter.string(from: dateRow)
    let yourDate = formatter.date(from: myString)
    formatter.dateFormat = "MM-dd-yyyy h:mm a"
    let myStringafd = formatter.string(from: yourDate!)

    cell.titleLabel.text = eventList[indexPath.row].title
    cell.dateStartLabel.text = "Start date: \(myStringafd)"
    if events[indexPath.row].conflict == true {

        cell.titleLabel.textColor = .red
    }else{
        cell.titleLabel.textColor = .black
    }
    return cell
}
如果要对显示进行分组,需要将数组组合成这样的日期,每组标题都可以使用
start

[
    [
        {
            "title": "Bicycling with Friends",
            "start": "11-01-2018"
        },
        {
            "title": "Yoga",
            "start": "11-01-2018"
        }
    ],
    [
        {
            "title": "Yoga",
            "start": "11-02-2018"
        }
    ]
]
我认为您的数据源可以保存一个二维数组
eventGroup
,或者一个带日期的字典
[dateString:[event]]
。只能将use
eventGroup
修改为这样

[
    {
        "title": "Bicycling with Friends",
        "start": "11-01-2018"
    },
    {
        "title": "Yoga",
        "start": "11-01-2018"
    },
    {
        "title": "Yoga",
        "start": "11-02-2018"
    }
]
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   return eventGroup[section].count
}

func numberOfSections(in tableView: UITableView) -> Int {
   return eventGroup.count
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let events = eventGroup[section]
    let event = events.first

    return event?.title //Replace with the header title you want
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "myCell", for: indexPath) as! MyTableCell

    let events = eventGroup[indexPath.section]
    let dateRow = events[indexPath.row].start
    let dateRowEnd = events[indexPath.row].end

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss"

    let myString = formatter.string(from: dateRow)
    let yourDate = formatter.date(from: myString)
    formatter.dateFormat = "MM-dd-yyyy h:mm a"
    let myStringafd = formatter.string(from: yourDate!)

    cell.titleLabel.text = eventList[indexPath.row].title
    cell.dateStartLabel.text = "Start date: \(myStringafd)"
    if events[indexPath.row].conflict == true {

        cell.titleLabel.textColor = .red
    }else{
        cell.titleLabel.textColor = .black
    }
    return cell
}

你需要先了解这个想法。想象一下,你的所有活动中只有一个部分。你想要什么样的模特

  • 头衔
  • 一连串的事件
对吧?


好的,如果上面说的有意义,那么你需要多个这样的模型。对吗?现在将其分解为更具体的术语。像实际的模型类型


因此,现在需要为表视图提供一个
对象数组


但是在此之前,您需要通过
startDate
对象对您的部分进行
分组Swift具有非常方便的
Dictionary
类型初始值设定项,允许我们通过从数组中的对象中选择特定属性的值来对数组进行分组。请注意以下功能:

func groupedSectionsByDate(from events: [Event]) -> [Section] {
    let grouped = Dictionary(grouping: events) { $0.startDate }
    // here you will need a date formatter object that will be used to convert
    // the Date type to String type. It's left as an assignment for the reader
    let dateFormatter: DateFormatter // init and configure it yourself
    let sections = grouped.map { Section(title: dateFormatter.string(from: $0.key), events: $0.value) }
    return sections 
}
上面的函数应该可以让您获得按日期分组的标题部分


现在,您将如何在表视图中使用它

class TableViewController: UITableViewController {
    . . .
    let sections = [Section]()
    . . .
    . . .
    func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return sections[section].count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        . . .
        let event = sections[indexPath.section].events[indexPath.row]
        . . .
    }
    . . .
    . . .
}

只需返回eventGroup[section]。按numberOfRows计数。在cellforrow中,您可以使用eventgroup[section][row]访问您的值。[section]来自何处?IndexPath.section然后您需要检查
事件组
,无论它是否是您想要的结构,请调整到您想要的
事件组
。这种方式完全按照
eventGroup
显示,每个元素都是一个组。例如,
var eventGroup=[[Event]、[Event]、[Event]]
相当于,有三个组,每个数组元素都是一个数组,每个单元格的内容都放在数组中。您希望每个组都是不同的日期,您需要重新筛选数据,将其存储在
eventGroup
中是的,您可以这样做否,这只是有助于理解分组后的格式。@soRazor,这不是正确的问题。您现在应该已经知道如何使用该方法以及在何处使用。告诉我,您以前是如何向表视图提供数据的?我没有问您在哪里。我问过你怎么做。让我直截了当地说。在代码中的某个地方,您可以将JSON转换为
事件
数组。这是应该为
groupedSectionsByDate(from:)
函数的参数提供的数组。函数返回应分配给实例属性
节的
数组。然后您需要调用
tableView.reloadData()
。为了避免在代码库中迷失方向,我建议您在单独的视图控制器类中,甚至在可能的情况下在单独的项目中尝试。