Swift 3和Firebase - Tableview不更新
问题描述:
Swift 3和Firebase - 我已经成功设法在tableview单元格中获取用户的用户名和电子邮件地址。但是,当用户在单独的视图控制器上更改他的用户名时,tableview不会更新 - 旧的用户名仍显示。请看看下面的代码:Swift 3和Firebase - Tableview不更新
databaseRef.child("users").queryOrdered(byChild: "username").observe(.childAdded, with: { (snapshot) in
let key = snapshot.key
let snapshot = snapshot.value as? NSDictionary
snapshot?.setValue(key, forKey: "uid")
if(key == self.loggedInUser?.uid)
{
// don't add signed in user to array
}
else
{
var theUser = User()
theUser.key = key
theUser.fullname = snapshot?.value(forKey: "fullname") as? String
theUser.biography = snapshot?.value(forKey: "biography") as? String
theUser.location = snapshot?.value(forKey: "location") as? String
theUser.photoURL = snapshot?.value(forKey: "photourl") as? String
theUser.username = snapshot?.value(forKey: "username") as? String
self.arrayOfUsers.append(theUser)
//insert the rows
self.SearchUsersTableViewController.insertRows(at: [IndexPath(row:self.arrayOfUsers.count-1,section:0)], with: UITableViewRowAnimation.automatic)
self.tableView.reloadData()
}
})
我曾尝试将tableview.reloadData()放在多个地方没有成功。我也尝试过使用:
DispatchQueue.main.async {
self.tableView.reloadData()
}
没有成功。当他改变他的用户名时,我想出了一个想法来再次追加用户。但是,我不知道如何删除旧的。我认为最好的解决方案是添加观察类型childChanged。问题是我找不到在用户数组中更改其用户名的用户的索引。
如果有人帮我解决问题,我将不胜感激。
编辑:
我有一个struct用户:
struct User {
var username: String?
var photoURL: String?
var biography: String?
var fullname: String?
var location: String?
var key: String?
}
对于.childChanged我已经使用该Priyamal建议的代码:
databaseRef.observe(.childChanged, with: { snapshot in
let ID = snapshot.key //this is the firebaseKey
if let index = self.arrayOfUsers.index(where: {$0.key == ID}) {
let changedPost = self.arrayOfUsers[index]
//update the values
self.tableView.reloadData()
print("Change!")
}
})
然而,当我更改用户名,我从来没有去过“改变!”输出在我的控制台;因此,tableview不会改变。
答
我认为你需要改变事件类型从childAdded
到childChanged
与孩子改变你只会得到更新的值。那么你必须更新数组中的现有元素。
让我们假设你的用户结构是这样的
struct User {
var keyID : String?
var name : String?
}
var userArray = [User]() //this represents the array holding user objects
这种方法将被调用,如果更新发生
databaseRef.observeEventType(.ChildChanged, withBlock: { snapshot in
let ID = snapshot.key //this is the firebaseKey
if let index = self. userArray.indexOf({$0.keyID == ID}) {
let changedPost = self. userArray[index]
//update the values
self.tableView.reloadData
}
在首位使用这种方法装载UserArray。
databaseRef.child("users").queryOrdered(byChild: "username").observe(.value, with: { (snapshot) in
let key = snapshot.key
let snapshot = snapshot.value as? NSDictionary
snapshot?.setValue(key, forKey: "uid")
if(key == self.loggedInUser?.uid)
{
print("Should not be shown!")
}
else
{
self.usersArray.append(snapshot)
self.SearchUsersTableViewController.insertRows(at: [IndexPath(row:self.usersArray.count-1,section:0)], with: UITableViewRowAnimation.automatic)
self.tableView.reloadData()
}
})
答
我已经成功地解决了这个问题。获得索引后,我只需要更新数组中特定位置的用户并刷新表视图中的特定行!
databaseRef.child("users").queryOrdered(byChild: "username").observe(.childChanged, with: { (snapshot) in
let ID = snapshot.key
if let index = self.arrayOfUsers.index(where: {$0.key == ID}) {
let value = snapshot.value as? NSDictionary
self.arrayOfUsers[index].username = value?["username"] as? String
let indexPath = IndexPath(item: index, section: 0)
self.tableView.reloadRows(at: [indexPath], with: .top)
}
})
然后数组根本没有填充。它只能通过使用.childAdded(甚至没有价值) –
现在试一试。这应该工作 – Priyamal
我得到一个错误:类型'NSDictionary?'的值?在这一行上没有成员'keyID':if let index = self.usersArray.indexOf({$ 0.keyID == ID}) –