ios UITableView在来自API的数据使用Codable之前显示

0tdrvxhp  于 2023-01-10  发布在  iOS
关注(0)|答案(4)|浏览(112)


当我运行应用程序时,我可以看到一个空白表,如下面的屏幕截图,加载了几毫秒,然后加载了实际数据。由于items数组在开始时有0个元素,numberOfRowsInSection返回0,并且正在加载空白表视图。是这样吗?请帮助我

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.items.count
}

我将上面的代码更改为下面的代码,但仍然存在相同的问题,在调试模式下,我发现打印(“Item array is empty”)执行了两次,然后空白表视图显示了几分之一秒,之后实际API调用发生,数据正确显示在表视图中
x一个一个一个一个x一个一个二个x

falq053o

falq053o1#

delegates方法可能会被多次调用。如果你想一开始就移除那些空单元格,你可以在viewDidLoad中添加:

bookTableView.tableFooterView = UIView()
5uzkadbs

5uzkadbs2#

您正在跨网络获取数据。这可能需要很长时间,尤其是在连接速度很慢的情况下。如果您在网络上等待,只要用户了解正在发生的事情,空的表视图并不一定是坏事。有几个解决方案,
1.在应用程序启动的早期获取数据并存储在本地。这种方法的问题是用户可能永远不需要下载的资源。例如,如果instantgram这样做了,那么用户将不需要大量的下载。如果你知道资源将被完全使用,那么尽早获取它,或者至少是你知道将被使用的一小部分。
2)甚至在segue之前就开始获取它。在你的代码中,你需要它用于表视图,但是你一直在等待视图的加载。这在生命周期中是相当晚的。
3)如果你必须让用户等待一个资源,让他们知道你正在加载。表格视图有一个刷新控件,你可以在你等待网络的时候调用它,或者使用一个进度指示器或微调器。你甚至可以隐藏你的整个视图,并显示一个视图,这样用户就知道发生了什么。
另外,tableview在自动加载时调用数据源,而您在代码中使用reloadData()时调用它,这就是为什么您会得到两次调用。
为了回答您的问题,这可以通过多种方式实现,您可以创建一个协议或对象示例的本地副本,即:在presentingViewController中使用MainVC,然后将获取代码移到那里,并在获取返回时在本地副本上设置项。只需向项变量添加一个didset,以便在设置变量时重新加载表视图。或者,理论上,您至少可以在segue中执行获取块,并在块中传递MainVC项。
比如说

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    let vc = segue.destination as MainVC
     
    self.fetchBooks { data in
        vc.items.self = data // not sure what the extra self is?
        DispatchQueue.main.async {
            vc.bookTableView.reloadData()
        }
    }
    
 }

因为闭包捕获了一个强指针,所以可以这样做。

fivyi3re

fivyi3re3#

通常我会做数据任务,如下面的代码显示,请参阅代码中的注解.

// show a spinner to users when data is loading
self.showSpinner()
DispatchQueue.global().async { [weak self] in
    
    // Put your heavy lifting task here,
    // get data from some completion handler or whatever
    loadData()

    // After data is fetched OK, push back to main queue for UI update
    DispatchQueue.main.async {
        self?.tableView.reloadData()
        // remove spinner when data loading is complete
        self?.removeSpinner()
    }
}
ukqbszuj

ukqbszuj4#

在确保调用了reloadData()之后,确保标签/图像的约束是正确的,这样可以确保标签/图像在单元格中可见。

相关问题