Ios 如何以编程方式从UITableView中删除行并更新UI
更新: 我已经找到了在更新Ios 如何以编程方式从UITableView中删除行并更新UI,ios,uitableview,swift3,xcode8,Ios,Uitableview,Swift3,Xcode8,更新: 我已经找到了在更新UITableView之前花费10秒的原因。它与我发送到服务器的HTTP POST请求有关。以下是我在阅读了所有答案并在线搜索后的代码。原因是放置了变量index,indepath,并调用了self.tableView(tableView:UITableView-UITableView,commit:UITableView-celleditingstyle,forRowAt:indepath) 如果我将它们移到任务闭包之外,它们会立即执行,但我不希望它们在外面,因为我需
UITableView
之前花费10秒的原因。它与我发送到服务器的HTTP POST请求有关。以下是我在阅读了所有答案并在线搜索后的代码。原因是放置了变量index
,indepath
,并调用了self.tableView(tableView:UITableView-UITableView,commit:UITableView-celleditingstyle,forRowAt:indepath)
如果我将它们移到任务
闭包之外,它们会立即执行,但我不希望它们在外面,因为我需要在删除之前从服务器获得“OK”
问题不在于服务器响应时间,因为我会立即得到响应。我认为这与我不太熟悉的task.resume()
有关
foreach expense in expenses {
var request = URLRequest(url: URL(string: Constants.ZEBON_SERVER_URL)!)
request.httpMethod = "POST"
let postString = "date=\(expense.date)&amount=\(expense.amount)¬e=\(expense.desc)"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) {
(data: Data?, response: URLResponse?, error: Error?) in
if error != nil {
print("error = \(error)")
}
// If the server responds with "OK" (the request was received) then delete the expense
if responseString?.range(of:"return\":\"ok") != nil {
let index = self.expenses.index(of: expense)
let indexPath = IndexPath(row: index!, section: 0)
// Deletes the expense
self.tableView(self.tableView, commit: .delete, forRowAt: indexPath)
}
else {
// TODO: Implement error handling.
}
}
task.resume()
}
原始问题:
我有一些对象显示在UITableView
中。当我按下按钮时,它们被发送到服务器,应该从tableView中删除
我当前的代码如下所示:
let index = self.expenses.index(of: expense)
let indexPath = NSIndexPath(row: index!, section: 0)
self.expenses.remove(at: indexPath.row)
// Saves the array 'Expenses' to persistent storage.
self.saveExpenses()
self.tableView.beginUpdates()
self.tableView.deleteRows(at: [indexPath as IndexPath], with: .none)
self.tableView.endUpdates()
我的问题是费用被发送到服务器并从存储中删除,但是
UITableView
不会刷新,因此单元格保持可见,而我无法以任何方式与它交互。在更新UI之后保存数组
实际上,这些行就足够了,begin/endUpdates()
对单个删除操作没有影响
let index = self.expenses.index(of: expense)
let indexPath = IndexPath(row: index!, section: 0)
self.expenses.remove(at: index!)
DispatchQueue.main.async {
self.tableView.deleteRows(at: [indexPath], with: .none)
}
// Saves the array 'Expenses' to persistent storage.
self.saveExpenses()
您是否在主线程上执行此操作?即使在使用tableview.ReloadData()之后?您需要将
self.tableview.ReloadData()添加到code@Maddyヅヅ 不,不要调用reloadData
。您在问题中发布的代码在哪里?提供一些上下文。并确保所有UI更新都在主线程上。我尝试在之后移动它,但就像上面Lion的回答一样,它非常慢(在单元格更新之前大约5秒),重新加载整个表视图比调用delete方法更昂贵。尝试更新主线程上的表视图。我更新了答案。将调用移动到saveExpenses
有什么区别吗?@rmaddy根据这么多经验,我知道许多编码人员都喜欢同步任务;-)我不知道你最后的评论如何回答我的问题。同样,移动self.saveExpenses()
如何改变任何事情?唯一相关的更改(可能,直到我们从OP听到更多)是确保对deleteRows
的调用在主队列上。