【发布时间】:2018-11-21 04:00:30
【问题描述】:
当我从有序数组加载数据时,表格视图会在加载时遍历每个单元格。似乎表格视图先加载,然后数组排序,这会导致闪烁效果。反过来,这也会弄乱每个细胞所拥有的图像。
快照获取数据后调用
postReference.observeSingleEvent(of: .value, with: { (snapshot) in
if let value = snapshot.value as? NSDictionary {
let post = Post()
let post_content = value["post"] as? String ?? "Content not found"
post.revealDate = value["revealedDate"] as? Double ?? 0000000
self.postList.append(post)
}
self.postList.sort() { $0.revealDate! > $1.revealDate! }
self.tableView.reloadData()
}
这会加载单元格
public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if queryComplete == true{
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! PostTableViewCell
//set cell content
let contentOfCellPost = postList[indexPath.row]
cell.label?.text = contentOfCellPost.post_words
return cell
似乎表格视图将每个单元格作为第一个单元格加载,然后对其进行排序。
编辑
整个firebase初始数据负载观察:
func fetchFeed () {
let UID = Auth.auth().currentUser?.uid
feedReference = Database.database().reference().child("feeds").child(UID!)
feedReference.keepSynced(true)
self.postRefHandle = feedReference.observe(.childAdded) { (snapshot) in
let postID = snapshot.key
let postReference = Database.database().reference().child("posts").child(postID)
postReference.observeSingleEvent(of: .value, with: { (snapshot) in
if let value = snapshot.value as? NSDictionary {
let post = Post()
let post_content = value["post"] as? String ?? "Content not found"
post.Reveals = value["reveals"] as? Int ?? 10000000
post.revealsRequired = value["revealsRequired"] as? Int ?? 100000
post.post_words = post_content
post.postID = postID
post.Revealed = value["Revealed"] as? String ?? "Revealed or Not not found"
post.revealsRequired = value["revealsRequired"] as? Int ?? 1000000000
post.revealDate = value["revealedDate"] as? Double ?? 0000000
post.timeOfDeletion = value["timeOfDeletion"] as? Int ?? 100000000000
if snapshot.hasChild("information") {
if let infoName = snapshot.childSnapshot(forPath: "information").value as? NSDictionary {
post.name = infoName["posterName"] as? String ?? "Poster not found"
post.profileImageLink = infoName["profileImage"] as? String ?? "nil"
post.revealedBool = true
self.postList.append(post)
}
} else {
let date = Date()
let currentTime = date.timeIntervalSince1970 * 1000
let timeToDelete = Int(post.timeOfDeletion!) - Int(currentTime)
post.revealedBool = false
post.name = String(timeToDelete)
self.postList.append(post)
}
self.postList.sort() { $0.revealDate! > $1.revealDate! }
self.tableView.reloadData()
}
})
}
}
观察帖子的变化:
postReference.observe(.value, with: { snapshot in
if self.queryComplete == true {
let changedKey = snapshot.key
if let index = self.postList.index(where: {$0.postID == changedKey}) {
let indexPath = IndexPath(row: index, section: 0)
let changedPost = self.postList[index]
if let value = snapshot.value as? NSDictionary {
let newReveals = value["reveals"] as? Int
changedPost.Reveals = newReveals
//update the values
self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
}
if let value = snapshot.value as? NSDictionary {
let newRevealStatus = value["Revealed"] as? String ?? "noRevealStatusChange"
changedPost.Revealed = newRevealStatus
if changedPost.Revealed == "true" {
changedPost.revealedBool = true
changedPost.revealDate = value["revealedDate"] as? Double ?? 00000
if let newName = snapshot.childSnapshot(forPath: "information").value as? NSDictionary {
changedPost.name = newName["posterName"] as? String ?? "Poster not found"
changedPost.profileImageLink = newName["profileImage"] as? String ?? "nil"
self.postList.sort() { $0.revealDate! > $1.revealDate! }
self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
}
}
}
}
}
self.queryComplete = true
} )
JSON 示例:
"feeds" : {
"3ASP4M5mkTPGPO1qQhfVKXsr6Qf2" : {
"-L65VFpW2cYIMxG2e9Ll" : "true",
"-L65VH5jkKPYAguzgqpn" : "true"
}
"posts" : {
"-L7CpeKT2lzsPALAfNti" : {
"Revealed" : "true",
"datePosted" : "2018-03-10 02:56:33 +0000",
"information" : {
"posterID" : "BmVot3XHEpYwMNtiucWSb8XPPM42",
"posterName" : "tester",
"profileImage" : "nil"
},
编辑:用更少的观察者修改代码:
func fetchFeed () {
let UID = Auth.auth().currentUser?.uid
feedReference = Database.database().reference().child("feeds").child(UID!)
feedReference.keepSynced(true)
self.postRefHandle = feedReference.observe(.childAdded) { (snapshot) in
let postID = snapshot.key
let postReference = Database.database().reference().child("posts").child(postID)
postReference.observe(.value, with: { (snapshot) in
let postKey = snapshot.key
if let value = snapshot.value as? NSDictionary {
if let index = self.postList.index(where: {$0.postID == postKey}) {
let indexPath = IndexPath(row: index, section: 0)
let changedPost = self.postList[index]
let newReveals = value["reveals"] as? Int
changedPost.Reveals = newReveals
//update the values
self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
let newRevealStatus = value["Revealed"] as? String ?? "noRevealStatusChange"
changedPost.Revealed = newRevealStatus
if changedPost.Revealed == "true" {
changedPost.revealedBool = true
changedPost.revealDate = value["revealedDate"] as? Double ?? 00000
if let newName = snapshot.childSnapshot(forPath: "information").value as? NSDictionary {
changedPost.name = newName["posterName"] as? String ?? "Poster not found"
changedPost.profileImageLink = newName["profileImage"] as? String ?? "nil"
self.postList.sort() { $0.revealDate! > $1.revealDate! }
self.roundButton.isHidden = false
}
}
self.tableView.reloadRows(at: [indexPath], with: UITableViewRowAnimation.none)
}
//appending to row for first time (initial load)
else {
if let value = snapshot.value as? NSDictionary {
let post = Post()
let post_content = value["post"] as? String ?? "Content not found"
post.Reveals = value["reveals"] as? Int ?? 10000000
post.revealsRequired = value["revealsRequired"] as? Int ?? 100000
post.post_words = post_content
post.postID = postID
post.Revealed = value["Revealed"] as? String ?? "Revealed or Not not found"
post.revealsRequired = value["revealsRequired"] as? Int ?? 1000000000
post.revealDate = value["revealedDate"] as? Double ?? 0000000
post.timeOfDeletion = value["timeOfDeletion"] as? Int ?? 100000000000
if snapshot.hasChild("information"){
if let infoName = snapshot.childSnapshot(forPath: "information").value as? NSDictionary {
post.name = infoName["posterName"] as? String ?? "Poster not found"
post.profileImageLink = infoName["profileImage"] as? String ?? "nil"
post.revealedBool = true
self.postList.append(post)
}
}
else {
let date = Date()
let currentTime = date.timeIntervalSince1970 * 1000
let timeToDelete = Int(post.timeOfDeletion!) - Int(currentTime)
post.revealedBool = false
post.name = String(timeToDelete)
self.postList.append(post)
}
// self.deletePosts()
self.postList.sort() { $0.revealDate! > $1.revealDate! }
self.tableView.reloadData()
}
}
}
else {
Database.database().reference().child("feeds").child(self.userIDCurrent!).child(postID).removeValue()
}
})
}
self.queryComplete = true
}
【问题讨论】:
-
@Code 不同,如何在添加单元格之前重新加载特定行?如何获取索引路径?
-
通过 .value 观察节点的代码看起来有点奇怪。您能否在问题中包含您的 Firebase 结构的 sn-p 作为文本,以便我们查看?
-
@Jay,我更新了代码。 json 结构使用扇出系统,以便帖子 ID 位于每个提要中。在观察数据时,我最初收集提要中的每个帖子,然后为初始加载创建一个单独的引用。然后,我为每篇只观察变化的帖子做一个参考,但为简洁起见,我没有包含代码。
-
事件的顺序有点不清楚,但我突然想到的一件事是(如果我误解了,请纠正我)你正在使用 postReference.observeSingleEvent填充 dataSource 数组,但在某些时候会发生这种情况 postReference.observe(.value 本质上将重新加载相同的数据但留下一个观察者。第一个观察更新整个 tableView,第二个更新那些相同的行再次。似乎所有这些都可以组合成一个观察者调用来填充帖子数组并让观察者观察这些帖子的变化。
标签: swift uitableview firebase firebase-realtime-database tableview