Update that object with the new info in array and to display tableview Swift

﹥>﹥吖頭↗ 提交于 2020-01-05 04:11:09

问题


I am using firebase realtime database and implementing user profile data with usersFriend and location. I need to implement the update in object array and show updated values in tableview. I have tried but I am not successful in updating object and then tableview reload. Function already developed.

I need to show updated object array swapped with new values and display in tableview.

var myFriendsDataSource = [FriendClass]()

func watchForChangesInMyFriends() { 
  let usersRef = self.ref.child("profiles") usersRef.observe(.childChanged, with: { snapshot in 
    let key = snapshot.key 
    if let friendIndex = self.myFriendsDataSource.firstIndex(where: { $0.uid == key} ) { 
      let friend = self.myFriendsDataSource[friendIndex] 
      print("found user \(friend.batteryStatus), updating")
      self.myFriendsDataSource[friendIndex] = friend 
      self.tableView.reloadData() 
    } 
  }) 
}

Class:

class FriendClass {

    var uid = ""
    var name = ""
    var batteryStatus = Int()
    var latitude = Double()
    var longitude = Double()
    var timeStamp = Int64()

    //var profilePic

    init(withSnapshot: DataSnapshot) {

        self.uid = withSnapshot.key
        self.name = withSnapshot.childSnapshot(forPath: "name").value as? String ?? "No Name"
        self.batteryStatus = withSnapshot.childSnapshot(forPath: "batteryStatus").value as? Int ?? 0
        self.latitude = withSnapshot.childSnapshot(forPath: "latitude").value as? Double ?? 0.0
        self.longitude = withSnapshot.childSnapshot(forPath: "longitude").value as? Double ?? 0.0
        self.timeStamp = withSnapshot.childSnapshot(forPath: "timeStamp").value as? Int64  ?? 0

    }
}

Updated:

func loadUsersFriends() {

let uid = "zzV6DQSXUyUkPHgENDbZ9EjXVBj2"
let myFriendsRef = self.ref.child("userFriends").child(uid)
myFriendsRef.observeSingleEvent(of: .value, with: { snapshot in
let uidArray = snapshot.children.allObjects as! [DataSnapshot]
   for friendsUid in uidArray {
          self.loadFriend(withUid: friendsUid.key)
          print(friendsUid)
         }
     })
 }

func loadFriend(withUid: String) {
  let thisUserRef = self.ref.child("profiles").child(withUid)
  thisUserRef.observeSingleEvent(of: .value, with: { snapshot in
  let aFriend = FriendClass(withSnapshot: snapshot)
  self.myFriendsDataSource.append(aFriend)
  print(self.myFriendsDataSource)
  self.tableView.reloadData()
  self.watchForChangesInMyFriends()

        })
    }

Update 2:

extension ViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 70
    }
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 10
    }
}

extension ViewController: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return myFriendsDataSource.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "FriendListTableViewCell", for: indexPath) as! FriendListTableViewCell
        let dic = myFriendsDataSource[indexPath.row]

        cell.frndName.text = dic.name

        return cell
    }


回答1:


Given the above comment discussion, I think you need to update your watchForChangesInMyFriends method as below to actually update the datasource with the new friend data. You should also do all your UI updates on the main thread, and as there is no guarantee that this closure will run on the main thread you need to force the tableView update onto the main thread.

func watchForChangesInMyFriends() { 
  let usersRef = self.ref.child("profiles") usersRef.observe(.childChanged, with: { snapshot in 
    let key = snapshot.key 
    if let friendIndex = self.myFriendsDataSource.firstIndex(where: { $0.uid == key} ) { 
      let friend = self.myFriendsDataSource[friendIndex] 
      print("found user \(friend.batteryStatus), updating")
      self.myFriendsDataSource[friendIndex] = FriendClass(withSnaphot: snapshot)
      DispatchQueue.main.async {
        self.tableView.reloadData()
      } 
    } 
  }) 
}

It's also better practice to update just the tableView data that has changed rather than reloading the whole tableView. You can probably use the array index to generate an IndexPath for the appropriate row and then just reload that row. Without seeing your tableView methods I can't be precise, but it'll probably look something like this:

let indexPath = IndexPath(row: friendIndex, section: 0)
DispatchQueue.main.async {
  self.tableView.reloadRows(at: [indexPath], with: .automatic)
}


来源:https://stackoverflow.com/questions/58623750/update-that-object-with-the-new-info-in-array-and-to-display-tableview-swift

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!