Ios 从Firebase删除后,Swift 3 UITableView未更新
当用户在UITableView上滑动以删除时,我试图从Firebase数据库中删除项目 我还使用了中的漂亮的showActivityIndicator和hideActivityIndicator函数,以便轻松显示和隐藏活动指示器 运行以下代码时,我可以看到数据库记录以及从Firebase中正确删除的JPG文件 但问题是,活动指示器永远不会从屏幕上消失,UITableView也不会刷新 事实上Ios 从Firebase删除后,Swift 3 UITableView未更新,ios,uitableview,firebase,swift3,Ios,Uitableview,Firebase,Swift3,当用户在UITableView上滑动以删除时,我试图从Firebase数据库中删除项目 我还使用了中的漂亮的showActivityIndicator和hideActivityIndicator函数,以便轻松显示和隐藏活动指示器 运行以下代码时,我可以看到数据库记录以及从Firebase中正确删除的JPG文件 但问题是,活动指示器永远不会从屏幕上消失,UITableView也不会刷新 事实上 print("Stopping activity indicator") 及 甚至不要跑 我做错了什么
print("Stopping activity indicator")
及
甚至不要跑
我做错了什么
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let alert = UIAlertController(title: "Delete Task", message: "Do you want to delete this task?", preferredStyle: .alert)
let confirmAction = UIAlertAction(title:"OK", style: .default) { action in
// Show activity indicator
ViewControllerUtils().showActivityIndicator(uiView: self.view)
// Retrieve Firebase reference to delete
let repairItem = self.repairItems[indexPath.row]
let storage = Storage.storage()
let storageRef = storage.reference()
let imageRef = storageRef.child(repairItem.imageRef)
// Delete the item from Firebase
repairItem.ref?.removeValue(completionBlock: {(error, ref) in
if let error = error {
print("Problem deleting item")
} else {
print("Item deleted successfully")
}
})
// Delete the photo
imageRef.delete { error in
if let error = error {
print("Problem deleting photo")
} else {
print("Photo deleted successfully")
}
}
print("Stopping activity indicator")
// Stop the activity indicator
ViewControllerUtils().hideActivityIndicator(uiView: self.view)
print("Reloading table view")
// Reloading table view
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel", style: .default)
alert.addAction(confirmAction)
alert.addAction(cancelAction)
present(alert, animated: true, completion: nil)
}
}
您需要在块内部编写代码,如下所示:
imageRef.delete { error in
if let error = error {
print("Problem deleting photo")
} else {
print("Photo deleted successfully")
ViewControllerUtils().hideActivityIndicator(uiView: self.view)
print("Reloading table view")
// Reloading table view
self.tableView.reloadData()
}
}
您需要在块内部编写代码,如下所示:
imageRef.delete { error in
if let error = error {
print("Problem deleting photo")
} else {
print("Photo deleted successfully")
ViewControllerUtils().hideActivityIndicator(uiView: self.view)
print("Reloading table view")
// Reloading table view
self.tableView.reloadData()
}
}
仍然不确定Firebase removeValue和delete函数下面的代码为什么没有运行,但我设法找到了一个解决方法 事实证明,只有当我删除表上最后一条剩余记录时,代码才起作用,之后整个Firebase节点都被删除 因此,我添加了一个观察者,以便在发生这种情况时强制重新加载表 在viewDidLoad()下,我添加了以下行:
override func viewDidLoad() {
super.viewDidLoad()
// ... other preceding lines of code
// Forcefully trigger a TableView refresh in case the Firebase node is empty
refItems.observe(.value, with: { snapshot in
if snapshot.exists() {
print("Found the Firebase node")
} else {
print("Firebase node doesn't exist")
self.tableView.reloadData()
}
})
// ...other following lines of code
}
仍然不确定Firebase removeValue和delete函数下面的代码为什么没有运行,但我设法找到了一个解决方法 事实证明,只有当我删除表上最后一条剩余记录时,代码才起作用,之后整个Firebase节点都被删除 因此,我添加了一个观察者,以便在发生这种情况时强制重新加载表 在viewDidLoad()下,我添加了以下行:
override func viewDidLoad() {
super.viewDidLoad()
// ... other preceding lines of code
// Forcefully trigger a TableView refresh in case the Firebase node is empty
refItems.observe(.value, with: { snapshot in
if snapshot.exists() {
print("Found the Firebase node")
} else {
print("Firebase node doesn't exist")
self.tableView.reloadData()
}
})
// ...other following lines of code
}
要使tableView和Firebase保持同步,有两个主要选项: 1) 从Firebase中删除节点时,请手动将其从 从Firebase中删除tableView数据源时。不需要观察员 2) 将移除事件观察者连接到Firebase,以便在移除节点时, 你的应用程序将收到它所在节点的事件,并将其删除 这里有一个例子;为了简洁起见,我省略了tableView代码 假设我们有一个显示用户的tableView。tableView有一个usersArray数据源,其中包含UserClass对象 给定一个火基结构
users
user_0
name: "Frank"
user_2
name: "Bill"
user_3
name: "Hugh"
我们向用户节点添加了三个观察者:childAdded、childChanged和childRemoved
class UserClass {
var key = ""
}
var usersArray = [UserClass]()
let usersRef = self.ref.child("users")
usersRef.observe(.childAdded, with: { snapshot in
let user = UserClass()
user.key = snapshot.key
self.usersArray.append(user)
self.tableView.reloadData()
})
usersRef.observe(.childChanged, with: { snapshot in
if let index = self.usersArray.index(where: {$0.key == snapshot.key}) {
//update it in the array via the index
self.tableView.reloadData()
} else {
//item not found
}
})
usersRef.observe(.childRemoved, with: { snapshot in
if let index = self.usersArray.index(where: {$0.key == snapshot.key}) {
self.usersArray.remove(at: index) //remove it from the array via the index
self.tableView.reloadUI()
} else {
item not found
}
})
如果添加了用户,.childAdded observer将接收新用户,以便将其追加到数组中
如果用户已更改,.childChanged观察者将接收更改的用户。抓取密钥(通常是uid),在数组中找到它并更新属性
如果删除了用户,.childRemoved observer将接收删除的用户。抓取密钥,在数组中找到它并将其移除
在每种情况下,在更改数据源后重新加载tableView。要使tableView和Firebase保持同步,有两个主要选项: 1) 从Firebase中删除节点时,请手动将其从 从Firebase中删除tableView数据源时。不需要观察员 2) 将移除事件观察者连接到Firebase,以便在移除节点时, 你的应用程序将收到它所在节点的事件,并将其删除 这里有一个例子;为了简洁起见,我省略了tableView代码 假设我们有一个显示用户的tableView。tableView有一个usersArray数据源,其中包含UserClass对象 给定一个火基结构
users
user_0
name: "Frank"
user_2
name: "Bill"
user_3
name: "Hugh"
我们向用户节点添加了三个观察者:childAdded、childChanged和childRemoved
class UserClass {
var key = ""
}
var usersArray = [UserClass]()
let usersRef = self.ref.child("users")
usersRef.observe(.childAdded, with: { snapshot in
let user = UserClass()
user.key = snapshot.key
self.usersArray.append(user)
self.tableView.reloadData()
})
usersRef.observe(.childChanged, with: { snapshot in
if let index = self.usersArray.index(where: {$0.key == snapshot.key}) {
//update it in the array via the index
self.tableView.reloadData()
} else {
//item not found
}
})
usersRef.observe(.childRemoved, with: { snapshot in
if let index = self.usersArray.index(where: {$0.key == snapshot.key}) {
self.usersArray.remove(at: index) //remove it from the array via the index
self.tableView.reloadUI()
} else {
item not found
}
})
如果添加了用户,.childAdded observer将接收新用户,以便将其追加到数组中
如果用户已更改,.childChanged观察者将接收更改的用户。抓取密钥(通常是uid),在数组中找到它并更新属性
如果删除了用户,.childRemoved observer将接收删除的用户。抓取密钥,在数组中找到它并将其移除
在每种情况下,在更改数据源后重新加载tableView。不,这仍然不起作用。活动指示器仍然显示,并且该项目在表视图上仍然可见。控制台上显示“照片已成功删除”和“重新加载表视图”消息,但活动指示器没有消失。我已经尝试删除showActivityIndicator和hideActivityIndicator,但现在表视图只是放在那里,没有删除行。有点,但我认为它“太快”了。我认为重新加载是在Firebase数据库条目被完全删除之前触发的,因此重新加载仍然会尝试从数据库中提取数据。如果我调度一个队列以异步删除数据库项和照片,可能效果会更好?不,它不会在数据库删除之前触发,因为在删除过程完成时块被调用。不,这仍然不起作用。活动指示器仍然显示,并且该项目在表视图上仍然可见。控制台上显示“照片已成功删除”和“重新加载表视图”消息,但活动指示器没有消失。我已经尝试删除showActivityIndicator和hideActivityIndicator,但现在表视图只是放在那里,没有删除行。有点,但我认为它“太快”了。我认为重新加载是在Firebase数据库条目被完全删除之前触发的,因此重新加载仍然会尝试从数据库中提取数据。如果我调度一个队列以异步删除数据库项和照片,可能效果会更好?不,它不会在数据库删除之前触发,因为在删除过程完成时会调用块。部分问题是Firebase是异步的。removeValue闭包后面的代码在从Firebase中移除项之前执行。还有一点不清楚是什么repairItem,repairItem.imageRef,以及预期的结果