我有一个表格,其中包含已登录用户和该应用的其他用户的附加消息。当我滑动单元格时,我希望能够从Firebase中删除它,也可以从tableView中自动删除它。我设法从Firebase中删除了单元格,但没有从tableView中删除。这是消息最初加载到tableView中的方式:
func loadData()
{
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in
if let postsDictionary = snapshot .value as? [String: AnyObject] {
for post in postsDictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
let info = value as! [String: AnyObject]
let convoId = info["convoId"]
let toId = info["ReceiverId"] as! String!
let fromId = info["senderId"] as! String!
if (toId == self.loggedInUserUid || fromId == self.loggedInUserUid) {
let refs = FIRDatabase.database().reference().child("user-messages").child(convoId as! String).child(uid)
refs.observe(.childAdded, with: { (snapshot) in
self.messageId = snapshot.key
let ref = FIRDatabase.database().reference().child("messages").child(convoId as! String).child(self.messageId!)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let message = Message(dictionary: dictionary)
if let receiver = message.convoId {
self.messagesDictionary[receiver] = message
self.messages = Array(self.messagesDictionary.values)
print(self.messages)
self.messages.sort(by: { (message1, message2) -> Bool in
return (message1.timestamp?.int32Value)! > (message2.timestamp?.int32Value)!
})
}
//this will crash because of background thread, so lets call this on dispatch_async main thread
DispatchQueue.main.async(execute: {
self.MessageTableView.reloadData()
})
}
}, withCancel: nil) })}
}
}}})
}
以下是我在Firebase中执行删除功能并尝试在tableView中执行删除功能的方法:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
let message = messages[(indexPath.row)]
self.deletemessage = message.convoId
FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in
if let postsDictionary = snapshot .value as? [String: AnyObject] {
for post in postsDictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
let info = value as! [String: AnyObject]
let convoId = info["convoId"]
let ref = FIRDatabase.database().reference().child("user-messages").child(self.deletemessage!).child(uid)
ref.observe(.childAdded, with: { (snapshot) in
self.messageId = snapshot.key
FIRDatabase.database().reference().child("user-messages").child(self.deletemessage!).child(uid).child( self.messageId!).removeValue(completionBlock: { (error, ref) in
if error != nil {
print("error \(error)")
}else{
}})})}}}})
self.messages.remove(at: indexPath.row)
self.MessageTableView.deleteRows(at: [indexPath], with: .automatic)
}
}
它从tableView中删除但崩溃并在self.messages.remove(at: indexPath.row)
致命错误上给出错误:索引超出范围。
答案 0 :(得分:0)
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let state = id[indexPath.row] //it store the child key to be removed. here id array is not displayed but used as backend process
print(state) // (Not required)
names.remove(at: indexPath.row) //Remove the selected name from array used in TableView that is displayed in cell
tableView.deleteRows(at: [indexPath], with: .fade) // TableView Animation
Database.database().reference().child("artists").child(id[indexPath.row]).removeValue() // remove the child referred using id from database
id.remove(at: indexPath.row) // removing selected if from id array locally
}
}
请尝试以下代码在您的情况下,请让我知道问题仍然存在
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
guard let uid = FIRAuth.auth()?.currentUser?.uid else {
return
}
let message = messages[(indexPath.row)]
self.deletemessage = message.convoId
FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in
if let postsDictionary = snapshot .value as? [String: AnyObject] {
for post in postsDictionary {
let messages = post.value as! [String: AnyObject]
for (id, value) in messages {
let info = value as! [String: AnyObject]
let convoId = info["convoId"]
let ref = FIRDatabase.database().reference().child("user-messages").child(self.deletemessage!).child(uid)
ref.observe(.childAdded, with: { (snapshot) in
self.messageId = snapshot.key
FIRDatabase.database().reference().child("user-messages").child(self.deletemessage!).child(uid).child( self.messageId!).removeValue(completionBlock: { (error, ref) in
if error != nil {
print("error \(error)")
}
})
})
}
}}})
self.messages.remove(at: indexPath.row)
self.MessageTableView.deleteRows(at: [indexPath], with: .automatic)
}
}
尝试这种情况会发生,因为您正在删除值正确但在处理程序下甚至在我的项目中导致错误。消息中的数据是从数据库加载的,因此如果不从数据库中删除值,即使从数组中删除,它也会再次更新。所以请试试这段代码