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

Posted

技术标签:

【中文标题】编程 .beginRefresh() 不刷新 UITableView 中的数据【英文标题】:Programmatic .beginRefresh() not refreshing data in UITableView 【发布时间】:2018-12-16 03:04:19 【问题描述】:

在我的 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 会正确重新加载,但在以编程方式调用拉刷新时不会。

【问题讨论】:

您需要在主队列上调度 UI 更新。 【参考方案1】:

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

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

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

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

【讨论】:

我尝试了您的解决方案。之前发生的同样的事情,.reloadData() 仅在用户通过手动拉刷新调用它时才工作,继续发生。

以上是关于编程 .beginRefresh() 不刷新 UITableView 中的数据的主要内容,如果未能解决你的问题,请参考以下文章

WPF中的DataGrid 数据动态刷新UI

jQuery UI 可拖动位置不刷新?

如何以编程方式刷新应用程序屏幕?

android 怎么刷新UI组件

WPF数据绑定,属性值更改UI不刷新其内容[重复]

Jquery UI自动完成列表不刷新