【问题标题】:Updating UITableView when returning from edit form, refresh entire table datasource or the row that was edited?从编辑表单返回时更新 UITableView,刷新整个表数据源或已编辑的行?
【发布时间】:2016-01-06 20:33:22
【问题描述】:

我的 viewDidLoad() 中有一个 UITableView,其中填充了来自 JSON 数据源的数据。我将此 JSON 数据存储在视图控制器代码顶部的字典中:

class InventoryListViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

    @IBOutlet var inventoryListTableView: UITableView!
    let textCellIdentifier = "textCell";
    var warehouseItems: [Inventory] = [];  //array for my items

    override func viewDidLoad() {
        super.viewDidLoad()

        inventoryListTableView.dataSource = self;
        inventoryListTableView.delegate = self;

        loadTableViewWithJSON();  //this loads my data into the warehouseItems dictionary created above

    }
...
}

这是我的loadTableViewWithJSON()

func loadTableViewWithJSON() {
        let urlString = "http://url.php";
        let session = NSURLSession.sharedSession();
        let url = NSURL(string: urlString)!;

        session.dataTaskWithURL(url) { (data: NSData?, response:NSURLResponse?, error: NSError?) -> Void in
            if let responseData = data {
                do {
                    let json = try NSJSONSerialization.JSONObjectWithData(responseData, options: NSJSONReadingOptions.AllowFragments) as! Dictionary<String, AnyObject>;

                    //                        print(json);

                    if let inventoryDictionary = json["inventory"] as? [Dictionary<String, AnyObject>] {
                        //                        print(inventoryDictionary);

                        for anItem in inventoryDictionary {

                            //                            print(anItem["quantityOnHand"] as? Int);  //works

                            if let id = anItem["id"] as? Int, let item = anItem["item"] as? String, let description = anItem["description"] as? String, let quantityOnHand = anItem["quantityOnHand"] as? Int, let supplierId = anItem["supplier_id"] as? Int, let supplierName = anItem["supplierName"] as? String {

                                let item = Inventory(id: id, item: item, description: description, quantityOnHand: quantityOnHand, supplierId: supplierId, supplierName: supplierName);
                                //                                print(item);

                                self.warehouseItems.append(item);
                            }
                        }
                        //                        print(self.warehouseItems[0].description); //works
                        dispatch_async(dispatch_get_main_queue(), {
                            self.inventoryListTableView.reloadData();
                        })
                    }
                } catch {
                    print("Could not serialize");
                }
            }

            }.resume()
        }

点击其中一个项目会进入另一个视图以编辑被点击的项目。当字段被更改并且项目被编辑时,会出现一个大的绿色检查,它调用一个休息 API 并更新我的数据库中的数据(我的 UITableView 从中获取)。现在,当我单击 NavigationController 中的“后退”按钮时,它会使用我的 UITableView 返回到上一个屏幕,但值不会更新。我试过在我的viewWillAppear() 中运行tableView.reloadData(),但没有任何效果。我也尝试调用我的函数来从 JSON 中获取数据,但当然这只是将更新的数据添加到我的 tableView 的末尾,我有一个旧的数据副本,下面还有一个新的。

我的问题是,我是否应该清除我的 UITableView 并再次运行我的函数来获取数据?还是应该只用新数据更新单行?我认为更新单行会更好,因为我的 RESTful API 开销更少。还是检测我何时从编辑视图控制器返回并重新加载所有数据会更好?

我试过了,但它不起作用:

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated);
        // loadTableViewWithJSON(); // this duplicates the data in the tableview
        inventoryListTableView.reloadData();
    }

还有我的cellForRowAtIndexPath

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(textCellIdentifier, forIndexPath: indexPath) as UITableViewCell;
        let row = indexPath.row;
        cell.textLabel!.text = "\(warehouseItems[row].item) -->  \(warehouseItems[row].quantityOnHand) on hand"

        cell.detailTextLabel!.text = warehouseItems[row].description;

        return cell;
    }

【问题讨论】:

  • 你能显示loadTableViewWithJSON()的正文吗(添加到原始问题)
  • 编辑完成。谢谢

标签: ios swift uitableview swift2


【解决方案1】:

当您调用loadTableViewWithJSON() 时,您调用的是self.warehouseItems.append(item),它只是附加到现有数组。这就是您在 tableView 中看到重复数据的原因。

warehouseItems = [] 添加到session.dataTaskWithURL(url) 响应块的顶部。这将清除数组,以便您可以使用更新的数据从头开始重建它。

func loadTableViewWithJSON() {
    let urlString = "http://url.php";
    let session = NSURLSession.sharedSession();
    let url = NSURL(string: urlString)!;

    session.dataTaskWithURL(url) { (data: NSData?, response:NSURLResponse?, error: NSError?) -> Void in
        if let responseData = data {
            warehouseItems = []

完成这些更改后,以下内容应该适合您。

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    loadTableViewWithJSON()
    inventoryListTableView.reloadData()
}

最后一点,在 Swift 中不需要分号,我们是免费的!

【讨论】:

  • 大声笑我知道分号。我发现他们出于某种原因感到安慰:)
  • 如果它们能给你带来欢乐,那我就无可争辩了。我的建议能否解决您的问题?
  • 我相信!我今天早上正在处理它。这很有意义,我不知道为什么我一开始就没有想到它。谢谢!
  • 它按预期工作,除了UITableView 在运行应用程序时第一次加载时,它显示重复。如果我选择某些内容,对其进行编辑,然后返回UITableView,它会显示正确和更新的值。现在只有表的初始加载有欺骗性。我知道这是因为我的viewDidLoad() 和我的viewWillAppear() 正在触发填充表格的功能。我不确定为什么它第一次忽略warehouseItems = []
  • 这可能是由于网络请求的异步特性。我已经更新了我的答案以考虑到这一点。
猜你喜欢
  • 2023-01-31
  • 1970-01-01
  • 2010-11-26
  • 2021-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-30
相关资源
最近更新 更多