【问题标题】:Reloading Data in TableView after completing parse function完成解析功能后重新加载TableView中的数据
【发布时间】:2020-11-13 16:23:36
【问题描述】:

我正在尝试在函数完成后重新加载数据:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if let presentingVC = presentingViewController as? DealsViewController {

 //checks if presenting VC's city is the same as original, doesn't run if it is      
 if presentingVC.city != self.currentCity {
        DispatchQueue.main.async {
            //reloads the data but before completion of the below function "getDealInfo"
            presentingVC.DealsTableView.reloadData()
            presentingVC.DealsTableView.layoutIfNeeded()
        }
    }
//checks if presenting VC's city is the same as original, doesn't run if it is        
if presentingVC.city != self.currentCity {
        presentingVC.city = self.currentCity
        presentingVC.deleteAllDeals()
        //this is the function that gets called
        presentingVC.getDealInfo()
        presentingVC.cityOutlet.setTitle(self.currentCity,for: .normal)
        }
       
    }
    tableView.deselectRow(at: indexPath, animated: true)
    searching = false
    self.dismiss(animated: true, completion: nil)
    searchBar.resignFirstResponder()
}

如您所见,我在返回上一个视图控制器以获取所提供的新信息后调用 reload 函数。但是,表格视图会在接收新值之前更新。结果,我的 tableView 是空的,但是我的值存储在我的数组中。

getDealInfo 是异步的:

    func getDealInfo() {
    let query = PFQuery(className: "Deal")
    query.whereKey("City", equalTo: city)
    query.order(byDescending: "Priority")
    query.findObjectsInBackground(block: { (objects: [PFObject]?,error: 
    Error?) in
    if let objects = objects {
        for object in objects {
            self.dealsArray.append(object["Deal"] as! String)
              }
            }
       }
    })
 }

【问题讨论】:

  • 那些是同步方法还是异步的?如果它们是同步的,只需重新排序您的代码。我不知道为什么你有两次相同的 if 语句

标签: ios swift uitableview parse-platform reload


【解决方案1】:

这些是同步方法还是异步方法?如果它们是同步的,只需重新排序您的代码。我不知道为什么你有两次相同的 if 语句。只需将其合二为一并在运行函数后调用 reload data

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

    if let presentingVC = presentingViewController as? DealsViewController {
//checks if presenting VC's city is the same as original, doesn't run if it is        
if presentingVC.city != self.currentCity {
        presentingVC.city = self.currentCity
        presentingVC.deleteAllDeals()
        //this is the function that gets called
        presentingVC.getDealInfo()
        presentingVC.cityOutlet.setTitle(self.currentCity,for: .normal)
         DispatchQueue.main.async {
            //reloads the data but before completion of the below function "getDealInfo"
            presentingVC.DealsTableView.reloadData()
            presentingVC.DealsTableView.layoutIfNeeded()
        }
        }
       
    }
    tableView.deselectRow(at: indexPath, animated: true)
    searching = false
    self.dismiss(animated: true, completion: nil)
    searchBar.resignFirstResponder()
}

如果它们是异步的,那么您需要考虑提供某种完成块。但是如果不知道 presentingVC.getDealInfo() 是否是异步的,就很难知道该建议什么。我觉得我们在这里遗漏了一些更重要的代码

【讨论】:

  • 感谢您这么快回复。它是异步的。我将如何显示这样的完成块?
【解决方案2】:

将完成处理程序添加到getDealInfo,以便在完成时收到通知:

func getDealInfo(_ completionHandler: @escaping () -> Void) {
    //Do async work
    completionHandler()
}

然后在调用代码中:

presentingVC.getDealInfo {
    self.presentingVC.DealsTableView.reloadData()
}

如果未在主线程中调用完成处理程序,那么您希望像当前​​一样使用DispatchQueue.main.async,因此对reloadData 的调用在主线程中完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-22
    • 1970-01-01
    • 1970-01-01
    • 2016-12-17
    • 2014-12-17
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    相关资源
    最近更新 更多