【问题标题】:Update or reload UITableView after completion of delete action on detail view完成详细视图上的删除操作后更新或重新加载 UITableView
【发布时间】:2016-10-08 04:42:07
【问题描述】:

我有一个通过 json 从 mysql 收集数据的 uitableview。然后它有一个详细视图,其中包含两个操作编辑和删除。编辑工作正常。删除操作会删除 mysql 数据,但问题是它不会从 uitableview 更新数据。

这是屏幕截图和代码

//表视图控制器

导入 UIKit 类 TableViewController: UITableViewController { var storeList = [商店]() //var storeList:Store? 覆盖 func viewDidLoad() { super.viewDidLoad() /* 如果让 s = storeList { txtName.text = s.storeName } */ // 取消注释以下行以保留演示文稿之间的选择 //self.clearsSelectionOnViewWillAppear = true // 取消注释以下行以在此视图控制器的导航栏中显示一个编辑按钮。 // self.navigationItem.rightBarButtonItem = self.editButtonItem() self.loadRecords() self.tableView.reloadData() } 覆盖 func viewWillAppear(动画:布尔){ super.viewWillAppear(动画) self.tableView.reloadData() // 重新加载选中的单元格 //tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) } 覆盖 func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // 处理所有可以重新创建的资源。 } // MARK: - 表格视图数据源 覆盖 func numberOfSectionsInTableView(tableView: UITableView) -> Int { // #warning 实现不完整,返回节数 返回 1 } 覆盖 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning 实现不完整,返回行数 返回 storeList.count } 覆盖 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { //let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) // 配置单元格... 让 cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as!商店TVC 让 s = storeList[indexPath.row] as Store cell.lblName.text = s.storeName //cell.lblID.text = s.storeId 返回单元格 } // 用于滑动删除 覆盖 func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 如果editingStyle == UITableViewCellEditingStyle.Delete { storeList.removeAtIndex(indexPath.row) tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) } } /* // 覆盖以支持表格视图的条件编辑。 覆盖 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 如果您不希望指定的项目可编辑,则返回 false。 返回真 } */ /* // 重写以支持编辑表格视图。 覆盖 func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 如果editingStyle == .Delete { // 从数据源中删除行 tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) } else if editingStyle == .Insert { // 创建相应类的新实例,将其插入到数组中,并在表格视图中添加新行 } } */ /* // 重写以支持重新排列表格视图。 覆盖 func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { } */ /* // 重写以支持表格视图的条件重新排列。 覆盖 func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 如果您不希望商品可重新订购,则返回 false。 返回真 } */ // MARK: - 导航 // 在基于故事板的应用程序中,您通常需要在导航前做一些准备工作 覆盖func prepareForSegue(segue:UIStoryboardSegue,发件人:AnyObject?){ // 使用 segue.destinationViewController 获取新的视图控制器。 // 将选中的对象传递给新的视图控制器。 /* 如果 segue.identifier == "详细信息" { //if let indexPath = tableView.indexPathForCell(sender as!UITableViewCell) if let indexPath = tableView.indexPathForSelectedRow { 让 s = storeList[indexPath.row] as Store 让 dvc = segue.destinationViewController 为!查看详情 dvc.store = s } } */ if let indexPath = tableView.indexPathForCell(sender as!UITableViewCell) { 让 s = storeList[indexPath.row] as Store 让 dvc = segue.destinationViewController 为!查看详情 dvc.store = s } } 函数加载记录() { //web服务的地址 让 urlString = "http://localhost/crud/read_for_table_view.php" // 1 - 通过获取配置然后创建会话来创建会话 让 config = NSURLSessionConfiguration.defaultSessionConfiguration() 让会话 = NSURLSession(配置:配置,委托:无,委托队列:无) //2 - 创建 URL 对象 如果让 url = NSURL(string: urlString) { //3 - 创建请求对象 让请求 = NSURLRequest(URL: url) //4 - 执行请求 让 taskData = session.dataTaskWithRequest(request, completionHandler: { (数据:NSData?,响应:NSURLResponse?,错误:NSError?)-> Void in //5 - 用返回的数据做一些事情 如果(数据!= 无) { //我们得到了一些数据 打印(“\(数据)”) /* var parseError:NSError? 让 parsedStores = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) as! NS词典 */ 做 { if let parsedStores = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary { print("Json 数据 \n \(parsedStores)") if let stores:AnyObject = parsedStores["result"] { self.parseJSON(存储) } } } 将错误捕获为 NSError { 打印(错误.localizedDescription) } }别的 { //我们有一个错误 print("获取商店时出错:\(error!.localizedDescription)") } }) 任务数据.resume() } } func parseJSON(jsonData:AnyObject) { 如果让 storeData = jsonData 为? [[NSObject:AnyObject]] { var 商店:商店 //我们循环遍历所有记录并且每次我们创建 // 一个对象存储然后添加到存储列表 对于 s 在 storeData { 商店=商店() // 这部分正在获取值 如果让 sId:AnyObject = s["id"] { 如果让 storeID = sId 为?细绳 { print("商店 id = \(storeID)") store.storeId = storeID } } 如果让 sn:AnyObject = s["name"] { if let storeName = sn as?细绳 { store.storeName = 商店名称 } } 商店列表 += [商店] } NSOperationQueue.mainQueue().addOperationWithBlock() { self.tableView.reloadData() } } } }

//详细视图

导入 UIKit 类 TableViewController: UITableViewController { var storeList = [商店]() //var storeList:Store? 覆盖 func viewDidLoad() { super.viewDidLoad() /* 如果让 s = storeList { txtName.text = s.storeName } */ // 取消注释以下行以保留演示文稿之间的选择 //self.clearsSelectionOnViewWillAppear = true // 取消注释以下行以在此视图控制器的导航栏中显示一个编辑按钮。 // self.navigationItem.rightBarButtonItem = self.editButtonItem() self.loadRecords() self.tableView.reloadData() } 覆盖 func viewWillAppear(动画:布尔){ super.viewWillAppear(动画) self.tableView.reloadData() // 重新加载选中的单元格 //tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) } 覆盖 func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // 处理所有可以重新创建的资源。 } // MARK: - 表格视图数据源 覆盖 func numberOfSectionsInTableView(tableView: UITableView) -> Int { // #warning 实现不完整,返回节数 返回 1 } 覆盖 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning 实现不完整,返回行数 返回 storeList.count } 覆盖 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { //let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) // 配置单元格... 让 cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as!商店TVC 让 s = storeList[indexPath.row] as Store cell.lblName.text = s.storeName //cell.lblID.text = s.storeId 返回单元格 } // 用于滑动删除 覆盖 func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 如果editingStyle == UITableViewCellEditingStyle.Delete { storeList.removeAtIndex(indexPath.row) tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) } } /* // 覆盖以支持表格视图的条件编辑。 覆盖 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 如果您不希望指定的项目可编辑,则返回 false。 返回真 } */ /* // 重写以支持编辑表格视图。 覆盖 func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 如果editingStyle == .Delete { // 从数据源中删除行 tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) } else if editingStyle == .Insert { // 创建适当类的新实例,将其插入到数组中,并在表格视图中添加新行 } } */ /* // 重写以支持重新排列表格视图。 覆盖 func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { } */ /* // 重写以支持表格视图的条件重新排列。 覆盖 func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 如果您不希望商品可重新订购,则返回 false。 返回真 } */ // MARK: - 导航 // 在基于故事板的应用程序中,您通常需要在导航前做一些准备工作 覆盖func prepareForSegue(segue:UIStoryboardSegue,发件人:AnyObject?){ // 使用 segue.destinationViewController 获取新的视图控制器。 // 将选中的对象传递给新的视图控制器。 /* 如果 segue.identifier == "详细信息" { //if let indexPath = tableView.indexPathForCell(sender as!UITableViewCell) if let indexPath = tableView.indexPathForSelectedRow { 让 s = storeList[indexPath.row] as Store 让 dvc = segue.destinationViewController 为!查看详情 dvc.store = s } } */ if let indexPath = tableView.indexPathForCell(sender as!UITableViewCell) { 让 s = storeList[indexPath.row] as Store 让 dvc = segue.destinationViewController 为!查看详情 dvc.store = s } } 函数加载记录() { //web服务的地址 让 urlString = "http://localhost/crud/read_for_table_view.php" // 1 - 通过获取配置然后创建会话来创建会话 让 config = NSURLSessionConfiguration.defaultSessionConfiguration() 让会话 = NSURLSession(配置:配置,委托:无,委托队列:无) //2 - 创建 URL 对象 如果让 url = NSURL(string: urlString) { //3 - 创建请求对象 让请求 = NSURLRequest(URL: url) //4 - 执行请求 让 taskData = session.dataTaskWithRequest(request, completionHandler: { (数据:NSData?,响应:NSURLResponse?,错误:NSError?)-> Void in //5 - 用返回的数据做一些事情 如果(数据!= 无) { //我们得到了一些数据 打印(“\(数据)”) /* var parseError:NSError? 让 parsedStores = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) as! NS词典 */ 做 { if let parsedStores = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary { print("Json 数据 \n \(parsedStores)") if let stores:AnyObject = parsedStores["result"] { self.parseJSON(存储) } } } 将错误捕获为 NSError { 打印(错误.localizedDescription) } }别的 { //我们有一个错误 print("获取商店时出错:\(error!.localizedDescription)") } }) 任务数据.resume() } } func parseJSON(jsonData:AnyObject) { 如果让 storeData = jsonData 为? [[NSObject:AnyObject]] { var 商店:商店 //我们循环遍历所有记录并且每次我们创建 // 一个对象存储然后添加到存储列表 对于 s 在 storeData { 商店=商店() // 这部分正在获取值 如果让 sId:AnyObject = s["id"] { 如果让 storeID = sId 为?细绳 { print("商店 id = \(storeID)") store.storeId = storeID } } 如果让 sn:AnyObject = s["name"] { if let storeName = sn as?细绳 { store.storeName = 商店名称 } } 商店列表 += [商店] } NSOperationQueue.mainQueue().addOperationWithBlock() { self.tableView.reloadData() } } } }

你能帮忙吗?

【问题讨论】:

  • 在返回 tableviewcontroller 时检查“storeList”是否包含已删除的项目。如果存在,则不会删除该项目。如果删除,更新 storeList 后 self.tableView.reloadData()

标签: ios json swift uitableview


【解决方案1】:

所以我得到了答案。

这里是更新

导入 UIKit 类 TableViewController: UITableViewController { var storeList = [商店]() //var storeList:Store? 覆盖 func viewDidLoad() { super.viewDidLoad() /* 如果让 s = storeList { txtName.text = s.storeName } */ // 取消注释以下行以保留演示文稿之间的选择 //self.clearsSelectionOnViewWillAppear = true // 取消注释以下行以在此视图控制器的导航栏中显示一个编辑按钮。 // self.navigationItem.rightBarButtonItem = self.editButtonItem() self.loadRecords() self.tableView.reloadData() } 覆盖 func viewWillAppear(动画:布尔){ super.viewWillAppear(动画) self.loadRecords() // 重新加载选中的单元格 //tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) } 覆盖 func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // 处理所有可以重新创建的资源。 } // MARK: - 表格视图数据源 覆盖 func numberOfSectionsInTableView(tableView: UITableView) -> Int { // #warning 实现不完整,返回节数 返回 1 } 覆盖 func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning 实现不完整,返回行数 返回 storeList.count } 覆盖 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { //let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) // 配置单元格... 让 cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as!商店TVC 让 s = storeList[indexPath.row] as Store cell.lblName.text = s.storeName //cell.lblID.text = s.storeId 返回单元格 } // 用于滑动删除 覆盖 func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 如果editingStyle == UITableViewCellEditingStyle.Delete { storeList.removeAtIndex(indexPath.row) tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic) } } /* // 覆盖以支持表格视图的条件编辑。 覆盖 func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 如果您不希望指定的项目可编辑,则返回 false。 返回真 } */ /* // 重写以支持编辑表格视图。 覆盖 func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) { 如果editingStyle == .Delete { // 从数据源中删除行 tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) } else if editingStyle == .Insert { // 创建适当类的新实例,将其插入到数组中,并在表格视图中添加新行 } } */ /* // 重写以支持重新排列表格视图。 覆盖 func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) { } */ /* // 重写以支持表格视图的条件重新排列。 覆盖 func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool { // 如果您不希望商品可重新订购,则返回 false。 返回真 } */ // MARK: - 导航 // 在基于故事板的应用程序中,您通常需要在导航前做一些准备工作 覆盖func prepareForSegue(segue:UIStoryboardSegue,发件人:AnyObject?){ // 使用 segue.destinationViewController 获取新的视图控制器。 // 将选中的对象传递给新的视图控制器。 /* 如果 segue.identifier == "详细信息" { //if let indexPath = tableView.indexPathForCell(sender as!UITableViewCell) if let indexPath = tableView.indexPathForSelectedRow { 让 s = storeList[indexPath.row] as Store 让 dvc = segue.destinationViewController 为!查看详情 dvc.store = s } } */ if let indexPath = tableView.indexPathForCell(sender as!UITableViewCell) { 让 s = storeList[indexPath.row] as Store 让 dvc = segue.destinationViewController 为!查看详情 dvc.store = s } } 函数加载记录() { //web服务的地址 让 urlString = "http://localhost/crud/read_for_table_view.php" // 1 - 通过获取配置然后创建会话来创建会话 让 config = NSURLSessionConfiguration.defaultSessionConfiguration() 让会话 = NSURLSession(配置:配置,委托:无,委托队列:无) //2 - 创建 URL 对象 如果让 url = NSURL(string: urlString) { //3 - 创建请求对象 让请求 = NSURLRequest(URL: url) //4 - 执行请求 让 taskData = session.dataTaskWithRequest(request, completionHandler: { (数据:NSData?,响应:NSURLResponse?,错误:NSError?)-> Void in //5 - 用返回的数据做一些事情 如果(数据!= 无) { //我们得到了一些数据 打印(“\(数据)”) /* var parseError:NSError? 让 parsedStores = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &parseError) as! NS词典 */ 做 { if let parsedStores = try NSJSONSerialization.JSONObjectWithData(data!, options: []) as? NSDictionary { print("Json 数据 \n \(parsedStores)") if let stores:AnyObject = parsedStores["result"] { self.parseJSON(存储) } } } 将错误捕获为 NSError { 打印(错误.localizedDescription) } }别的 { //我们有一个错误 print("获取商店时出错:\(error!.localizedDescription)") } }) 任务数据.resume() } } func parseJSON(jsonData:AnyObject) { storeList.removeAll() 如果让 storeData = jsonData 为? [[NSObject:AnyObject]] { var 商店:商店 //我们循环遍历所有记录并且每次我们创建 // 一个对象存储然后添加到存储列表 对于 s 在 storeData { 商店=商店() // 这部分正在获取值 如果让 sId:AnyObject = s["id"] { 如果让 storeID = sId 为?细绳 { print("商店 id = \(storeID)") store.storeId = storeID } } 如果让 sn:AnyObject = s["name"] { if let storeName = sn as?细绳 { store.storeName = 商店名称 } } 商店列表 += [商店] } NSOperationQueue.mainQueue().addOperationWithBlock() { self.tableView.reloadData() } } } }

【讨论】:

  • 在 viewWillAppear 中有两件事我添加了 self.loadRecords()。另一个是 parseJSON 我添加了 storeList.removeAll()
【解决方案2】:

这里是比viewWillAppear 中的reload tableview 更好的解决方案。使用委托的方法。

在您的 Detail View 控制器上添加。

weak var delegate : TableViewController!

修改Table View Controller

上的代码行
if segue.identifier == "details"{
    if let indexPath = tableView.indexPathForSelectedRow{
      let s = storeList[indexPath.row] as Store
      let dvc = segue.destinationViewController as! ViewDetails
      dvc.store = s
      dvc.delegate = self
    }
}

在您的详细信息视图上完成操作时或在关闭详细信息视图之前。在您的详细视图中执行以下行。

self.delegate.tableView.reloadData()

在这里,我希望这是更好的方法和最佳实践,而不是您的方法。试试吧。 :)

【讨论】:

  • 让详细视图知道代理有一个 tableView 有点奇怪。
【解决方案3】:

试试下面的代码:

override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if editingStyle == UITableViewCellEditingStyle.Delete {
        storeList.removeAtIndex(indexPath.row)
        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
        self.loadRecords()
    }
}

希望对你有帮助

【讨论】:

    【解决方案4】:

    我知道这是一个老问题,但我的 2 美分是,如果你想重新加载你的 tableview,只要你以任何方式更新你的 storeList 数组,你就可以使用didSet 当像这样声明你的 storeList 时:

     var storeList: [Store] = []{
            didSet{
                DispatchQueue.main.async {
                    self.tableView.reloadData()
                }
            }
        }
    

    有了上面的内容,你的意思是,任何时候storeList数组以任何方式删除、添加或更新内容,然后在主UI上重新加载tableView,这样你就不需要手动进行更改到您的 tableView,但对 storeList 的更改将触发对 tableView 的更改

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多