使用数组中的新信息更新该对象,并显示tableview Swift [英] Update that object with the new info in array and to display tableview Swift

查看:116
本文介绍了使用数组中的新信息更新该对象,并显示tableview Swift的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Firebase实时数据库,并通过usersFriend和location实施用户个人资料数据.我需要在对象数组中实现更新,并在tableview中显示更新的值.我已经尝试过,但是我没有成功更新对象,然后重新加载tableview.功能已经开发.

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.

我需要显示更新的对象数组与新值交换并显示在tableview中.

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 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

    }
}

已更新:

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()

        })
    }

更新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
    }

推荐答案

鉴于上面的评论讨论,我认为您需要按如下所示更新您的watchForChangesInMyFriends方法,以使用新的好友数据实际更新数据源.您还应该在主线程上进行所有UI更新,并且由于不能保证此闭包将在主线程上运行,因此您需要将tableView更新强制到主线程上.

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()
      } 
    } 
  }) 
}

更好的做法是只更新已更改的tableView数据,而不是重新加载整个tableView.您可能可以使用数组索引为相应的行生成一个IndexPath,然后重新加载该行.没有看到您的tableView方法,我无法精确确定,但看起来可能像这样:

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)
}

这篇关于使用数组中的新信息更新该对象,并显示tableview Swift的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆