组数组以在 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.count
和 return 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 中向 UITableView 添加按日期分隔的部分
编写自定义指令以在 AngularJS (TypeScript) 中向 ng-options 添加工具提示
text 在Mac OSX中向Finder服务添加命令以在VS Code中打开文件夹