组数组以在 Swift 中向 UITableView 引入部分

Posted

技术标签:

【中文标题】组数组以在 Swift 中向 UITableView 引入部分【英文标题】:Group Array to introduce sections to UITableView in Swift 【发布时间】:2020-01-15 14:41:09 【问题描述】:

我有以下课程:

ChatMessage: Codable 
    var id: Int?
    var sender: User?
    var message: String?
    var seen: Int?
    var tsp: Date?

tsp 格式如下:YYYY-MM-DD hh:mm:ss

我想对同一天发送的消息进行“分组”,最终得到如下示例中的内容:

let groupedMessages = [ [ChatMessage, ChatMessage], [ChatMessage, ChatMessage, ChatMessage] ]

我最终想在 UITableViewController 中使用 groupedMessages 来引入如下部分:

func numberOfSections(in tableView: UITableView) -> Int 
        return groupedMessages.count 
        // would be 2 int the above
    



    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? 
        return chatMessages[section].count 
        // would be 2 for the first and 3 for the second section
    

完成排序的最高效方式是什么? - 即,一旦要排序的聊天消息数量增加,它也能正常工作

【问题讨论】:

【参考方案1】:

你可以试试:

let cal = Calendar.current
let groupedMessages = Dictionary(grouping: self.chatMessages, by:  cal.startOfDay($0.tsp) )
let keys = groupedMessages.keys.sorted(by:  $0 > $1 )

然而,这会给你一个像这样的字典:

[
  SomeDateHere: [
    ChatMessage(id: 0, sender: User?, message: "String", seen: 1),
    ChatMessage(id: 0, sender: User?, message: "String", seen: 1)
  ],
  AnotherDateHere: [
    ChatMessage(id: 0, sender: User?, message: "String", seen: 1)
]

然后您可以使用键返回节数:

return keys.count

并像这样获取每个字典项的消息数组:

let key = keys[indexPath.section]
let messages = groupedMessages[key].sorted(by:  $0.tsp > $1.tsp )

或者只获取计数:

let key = keys[indexPath.section]
return groupedMessages[key].count

【讨论】:

看起来是个不错的解决方案。但是字典似乎不太适合在 UITableView 部分中使用。至少我不知道如何 / 用什么替换我的代码中的 return groupedMessages.countreturn chatMessages[section].count 以使其再次工作。如果不知道字典的键,我该怎么做? 分组将为您创建密钥。然后你可以像我上面提供的例子一样使用它们。 太棒了——效果很好!!!最后一个快速的问题:我调用的 api 首先返回最新的聊天消息,这是有道理的。但是当我在 cellForRowAt 中简单地将它们出队时,它会在屏幕底部显示最旧的消息 - 即完全错误的顺序。在将排序闭包提供给排序闭包之前,有没有一种快速的方法来翻转排序的字典 - 或者消息数组?非常感谢您的帮助!!! 刚刚更新了我的答案,向您展示如何对每个部分中的消息进行排序。如果项目没有按照您喜欢的顺序排列,您可以通过将> 更改为< 来更改排序方式。 像个迷人的人一样工作 ;-) 非常感谢您的宝贵时间和帮助!!!【参考方案2】:

您可以在这里找到按日期分组数组How to group array of objects by date in swift?

如何将它连接到 UITableView,您可以在这里找到https://www.ralfebert.de/ios-examples/uikit/uitableviewcontroller/grouping-sections/

【讨论】:

【参考方案3】:

我可能会从引入一种新类型开始:

public struct CalendarDay: Hashable 
   public let date: Date

   public init(date: Date = Date()) 
       self.date = Calendar.current.startOfDay(for: date)
   


extension CalendarDay: Comparable 
   public static func < (lhs: CalendarDay, rhs: CalendarDay) -> Bool 
      return lhs.date < rhs.date
   

然后我会扩展您的信息:

extension ChatMessage 
    var day: CalendarDay 
       return CalendarDay(date: tsp)
    

(我假设tsp 不是可选的,没有理由让它成为可选的)。

现在,让我们定义一个部分:

struct Section 
   var messages: [ChatMessage] = []
   let day: CalendarDay

   init(day: CalendarDay) 
      self.day = day
   

让我们轻松分组:

let messages: [ChatMessage] = ...
var sections: [CalendarDay: Section] = [:]

for message in messages 
   let day = message.day
   var section = sections[day] ?? Section(day: day)
   section.messages.append(day)
   sections[day] = section


let sectionList = Array(sections.values).sorted  $0.day < $1.day 

如果您的消息最初没有排序,您可能还需要单独对每个部分中的消息进行排序。

【讨论】:

【参考方案4】:
let testArray = ["2016-06-23 09:07:21", "2016-06-23 08:07:21", "2016-06-22 09:07:21", "2016-06-22 08:07:21"]

        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "YYYY-MM-DD hh:mm:ss"

        let groupDic = Dictionary(grouping: testArray)  (pendingCamera) -> DateComponents in

            let date = Calendar.current.dateComponents([.day, .year, .month], from: dateFormatter.date(from: pendingCamera)!)

            return date
        
        print(groupDic)

您可以使用 groupDic 并在 numberOfSections 和 titleForHeaderInSection 中返回。

【讨论】:

以上是关于组数组以在 Swift 中向 UITableView 引入部分的主要内容,如果未能解决你的问题,请参考以下文章

减少数组以在 Swift 中设置

在 Swift 中向 UITableView 添加按日期分隔的部分

编写自定义指令以在 AngularJS (TypeScript) 中向 ng-options 添加工具提示

text 在Mac OSX中向Finder服务添加命令以在VS Code中打开文件夹

text 在Mac OSX中向Finder服务添加命令以在VS Code中打开文件夹

如何从属于 UITableView 中的模型数组对象的数组中向 tableView 显示数据?