我在从Firebase获取异步操作中的数据后尝试reloadData()
。我很难找到合适的位置来执行reloadData()
在不同的位置,它要么刷新tableView的一部分而不刷新另一部分,要么根本不刷新,或者更糟糕的是,刷新会使数据集。
到目前为止,这是我的代码,以及我在该特定位置reloadData()
时的结果说明:
func getData() {
DispatchQueue.main.async {
self.titleView.setTitle(viewController: self, animate: true, title: "Updating...")
}
ref.child("conversations").child(userUID).observeSingleEvent(of: .value) { (snapshot) in
for snap in snapshot.children {
let snapDatasnapshot = snap as! DataSnapshot
let snapValues = snapDatasnapshot.value as! [String: AnyObject]
let recipientUID = snapDatasnapshot.key
for (key, value) in snapValues {
let conversationStartTime = value["conversationStartTime"] as! Double
if calculateMinutesLeft(conversationStartTime) >= 0 {
let messagesDatasnapshot = snapDatasnapshot.childSnapshot(forPath: shoutoutID).childSnapshot(forPath: "messages")
let messagesArray = messagesDatasnapshot.value as! [String: AnyObject]
self.startTimeDictionary[shoutoutID] = conversation
for message in messagesArray {
let messageID = message.key
self.ref.child("messages").child(messageID).observeSingleEvent(of: .value, with: { (messagesSnapshot) in
let dictionary = messagesSnapshot.value as! [String: AnyObject]
let timestamp = dictionary["timestamp"] as! Double
let readReceipt = dictionary["readReceipt"] as! Bool
if let messageText = dictionary["message"] {
let message = messageText as! String
let m = Message(fromUserUID: self.userUID, message: message, timestamp: timestamp, recipientUserUID: recipientUID, imageUrl: nil, readReceipt: readReceipt)
self.messagesDictionary[conversation] = m
self.messages = Array(self.messagesDictionary.values)
}
//Location 1
DispatchQueue.main.async {
self.tableView.reloadData()
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
})
}
} else {
//Expired Convos
self.expiredConversations.append(conversation)
//Location 2
DispatchQueue.main.async {
self.tableView.reloadData()
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
}
}
}
if self.messages.isEmpty && self.expiredConversations.isEmpty {
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
//Location 3
DispatchQueue.main.async {
self.tableView.reloadData()
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
}
//Location 4
DispatchQueue.main.async {
self.tableView.reloadData()
self.titleView.setTitle(viewController: self, animate: false, title: "Chats")
}
}
messages
将显示在tableView的第0部分,而expiredConversations
将显示在tableView的第1部分。
我当前的实现是在位置1和2.这样做正确地重新加载表的两个部分,但是当刷新多次或者当tableView的大小太大时,往往会混淆数据。否则:
messages
和expiredConversations
对reloadData()
的最佳位置或理想位置有何建议?或者我的实施完全错了?
编辑:tableViewDelegate和tableViewDatasource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
switch section {
case 0:
if messages.isEmpty {
return 1
} else {
return messages.count
}
case 1:
return expiredConversations.count
default:
return 0
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
switch indexPath.section {
case 0:
if messages.isEmpty {
let noConversationsCell = tableView.dequeueReusableCell(withIdentifier: "noConversationsCell", for: indexPath) as! NoActiveConversationsTableViewCell
noConversationsCell.isUserInteractionEnabled = false
return noConversationsCell
} else {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! ChatLogTableViewCell
let message = messages[indexPath.row]
let conversation = conversations[indexPath.row]
//All the data model thing to populate the cells
return cell
}
case 1:
let expiredConversationsCell = tableView.dequeueReusableCell(withIdentifier: "expiredConversationsCell", for: indexPath) as! ExpiredConversationsTableViewCell
let conversation = expiredConversations[indexPath.row]
//All the data model thing to populate the cells
return expiredConversationsCell
default:
return UITableViewCell()
}
}