程序化.beginRefresh()不刷新UITableView中的数据

时间:2018-12-16 03:04:20

标签: ios swift uitableview alamofire

在我的TableViewController中,我有一个@objc函数,该函数使用Alamofire获取数据。当用户拉下触发拉动刷新时,该函数由refreshController调用。

拉刷新的声明如下:

let refreshControl = UIRefreshControl()
tableView.refreshControl = refreshControl
self.refreshControl!.addTarget(self, action: #selector(refresh(sender:)), for: .valueChanged)

它运行的功能:

@objc func refresh(sender:AnyObject) {
    let defaults = UserDefaults.standard
    if let mode = defaults.string(forKey: defaultsKeys.mode) {
        self.mode = mode
    }
    self.tableData.removeAll()
    print(mode)
    Alamofire.request(mode).response { response in
        let xml = SWXMLHash.config {
            config in
            config.shouldProcessLazily = true
            }.parse(response.data!)
        for elem in xml["rss"]["channel"]["item"].all {
            self.tableData.append(elem["title"].element!.text)
        }
        print("Completed Data Gather")
        self.mainTable?.reloadData()
        self.refreshControl!.endRefreshing()
    }
}

当我尝试使用

以编程方式调用拉刷新功能时,就会出现问题
self.refreshControl!.beginRefreshing()
self.refreshControl!.sendActions(for: .valueChanged)

该函数执行(由于打印语句而在控制台中观察到),并且已获取数据,但tableView拒绝刷新。我知道数据已正确提取,因为下次用户再次手动拉出时,会使用新数据刷新tableView更新。

TL; DR 我的tableView在用户手动进行拉动刷新时正确地重新加载,但是在以编程方式使用拉动刷新时不会正确地重新加载。

1 个答案:

答案 0 :(得分:1)

正如Paul在评论中提到的,这是因为UI更新必须在主线程上分派。

Alamofire是异步的,并且在后台线程上运行。话虽如此,您的Alamofire请求中的所有代码都将在后台线程上执行。

为了在主线程上执行代码,请利用以下内容:

DispatchQueue.main.async {
    // Update UI ie. self.mainTable?.reloadData()
}