Это не может быть ответ , но это может привести к ответу.Как отмечено в комментариях, для управления источником данных для tableView используются два массива.Один содержит данные, а другой использует технику индексирования - я считаю, что это может привести к проблемам, подобным описанному в вопросе.
Другая проблема заключается в том, что, когда каждый дочерний элемент добавляется изначально, мы повторно сортируеммассив, а затем обновить tableView - это может привести к задержкам и мерцанию.(мерцание = плохо)
Итак, давайте установим пару вещей.Сначала класс, который содержит сообщения
PostClass {
var post_id = ""
var post_text = ""
var creation_date = ""
}
, затем структура Firebase, которая похожа на
posts
post_id_0
text: "the first post"
timestamp: "20190220"
post_id_1
text: "the second post"
timestamp: "20190221"
, а затем небольшая хитрость для заполнения источника данных и оставления дочернего наблюдателя.Это важно, так как вы не хотите обновлять tableView с каждым дочерним элементом, который может (будет) мерцать.Поэтому мы используем, чтобы события childAdded всегда предшествовали событиям .value, чтобы массив заполнялся, а затем .value обновит его один раз, а затем мы будем обновлять tableView каждый раз после.Вот некоторый код - много чего происходит, поэтому пошагово пройдитесь.
var postsArray = [String]()
var initialLoad = true
func ReadPosts() {
let postsRef = self.ref.child("posts").queryOrdered(byChild: "timestamp")
postsRef.observe(.childAdded, with: { snapshot in
let aPost = PostClass()
aPost.post_id = snapshot.key
aPost.post_text = snapshot.childSnapshot("text").value as! String
aPost.creation_date = snapshot.childSnapshot("timestamp").value as! String
self.postsArray.append(aPost)
//upon first load, don't reload the tableView until all children are loaded
if ( self.initialLoad == false ) {
self.postsTableView.reloadData()
}
})
//when a child is removed, the event will contain that child snapshot
// we locate the child node via it's key within the array and remove it
// then reload the tableView
postsRef.observe(.childRemoved, with: { snapshot in
let keyToRemove = snapshot.key
let i = self.postsArray.index(where: { $0.post_id == keyToRemove})
self.postsArray.remove(at: i)
self.postsTableView.reloadData()
})
//this event will fire *after* all of the child nodes were loaded
// in the .childAdded observer. So children are sorted, added and then
// the tableView is refreshed. Set initialLoad to false so the next childAdded
// after the initial load will refresh accordingly.
postsRef.observeSingleEvent(of: .value, with: { snapshot in
self.postsTableView.reloadData()
self.initialLoad = false
})
}
На что обратить внимание
Мы позволяем Firebase выполнять тяжелую работу и упорядочивать узлы с помощью creation_date, чтобы они вошлиorder.
Это будет вызвано, скажем, viewDidLoad, где мы установим initialLoad
класс var изначально равным true