Заказал эффект мерцания массива? - PullRequest
0 голосов
/ 11 июня 2018

Когда я загружаю свои данные из упорядоченного массива, представление таблицы проходит каждую ячейку при загрузке.Кажется, будто сначала загружается табличное представление, а затем упорядочивается массив, что приводит к эффекту мерцания.Это, в свою очередь, также портит изображения, которые есть у каждой клетки.

Вызывается после того, как снимок получает данные

     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

This is how the posts flicker when the table view loads

Кажется, что представление таблицы загружает каждую ячейку как первую ячейку, а затем упорядочивает ее.

EDIT

Наблюдение за начальной загрузкой данных всей базы данных:

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
}

1 Ответ

0 голосов
/ 13 июня 2018

Я собираюсь сделать попытку и подойти к вопросу, предложив альтернативное направление.Если это далеко от базы, дайте мне знать, и я могу обновить или удалить.

В этом вопросе много кода для сортировки, но на первый взгляд кажется, что добавлено большое количество наблюдателей, которые перезагружаютданных и частого обновления tableView.

Из того, что я вижу, узел каналов используется для сбора групп данных;группа сообщений, в которых заинтересован пользователь, группа дат, группа друзей и т. д., каждая из которых является фидом, и к каждому узлу, связанному с этим фидом, добавлен наблюдатель.

Мое предложение состоит в том, чтобы пойтина более высоком уровне - вместо того, чтобы обращаться к каждому дочернему узлу с отдельным независимым наблюдателем, скажем «Эй, Firebase, внутри этого родительского узла, если дочерний узел соответствует определенным критериям, сообщите пользователю об этом»

Итак, давайте используем глубокие запросы Firebase, чтобы сделать то же самое с гораздо меньшим количеством наблюдателей.

Возьмем пример структуры сообщений

posts
   post_0
     name: "Jim"
     post: "We have them just where they want us"
     watched_by:
        uid_0: true
        uid_1: true
   post_1
     name: "Spock"
     post: "Nothing unreal exists"
     watched_by:
        uid_1: true
   post_2
     name: "Bones"
     post: "I'm a doctor, not an escalator"
     watched_by
        uid_0: true

и предположим, что пользователь с uid_0 аутентифицируется.Ранее они решили посмотреть посты Джима и Кости.Как вы можете видеть из структуры, у нас есть узел watched_by в каждом сообщении и мы добавили uid_0: true к этому узлу.

Итак, давайте теперь позволим uid_0 наблюдать за узлом сообщений на предмет изменений в сообщениях, которыми они являются.интересует:

let postsRef = self.ref.child("posts")
let watchedByQuery = postsRef.queryOrdered(byChild: "/watched_by/uid_0").queryEqual(toValue: true)
watchedByQuery.observe(.childChanged, with: { snapshot in
    let dict = snapshot.value as! [String: Any]
    let post = dict["post"] as! String
    print(snapshot.key, post)
})

поэтому, если Кости войдет в систему и изменит свой пост с «Я врач, а не эскалатор» на «Я врач, а не каменщик», этот узел будет отправленк uid_0, чтобы пользовательский интерфейс мог быть обновлен.

   post_2
     name: "Bones"
     post: "I'm a doctor, not a bricklayer"
     watched_by
        uid_0: true

расширяя это, мы, очевидно, добавили бы .childAdded и .childRemoved, используя ту же технику, и .childAdded заполнил бы наш источник данных tableView первоначально для каждого пользователя, так какони аутентифицируются.

Предположим, Кости затем полностью удаляет свой пост (узел).Любой пользователь в списке watched_by будет уведомлен об этом событии (даже миллионы пользователей).Когда это происходит, в коде прочитайте ключ post_2 из моментального снимка, найдите его в своем массиве источника данных, удалите его и обновите tableView.

Опять же - полный ответ в мрачном ответе с моей стороны.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...