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)&note=\(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
的调用在主队列上。