我有一个水平滚动UICollectionView
,每个collectionViewCell
包含一个tableView
,其中显示了post
个对象的提要。我只想为每个collectionViewCell
获取一次数据。
我当前的实现是在collectionViewCell
出队时获取数据,即,当用户在collectionView
上左右滑动时,单元有时会重新加载并获取数据,从而中断用户体验。
到目前为止的代码:
//At ViewController
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! FeedCell
cell.topic = topics[indexPath.item]
return cell
}
//At FeedCell, the custom collectionViewCell
class FeedCell: UICollectionViewCell {
lazy var tableView: UITableView = {
let tv = UITableView(frame: .zero, style: .plain)
tv.delegate = self
tv.dataSource = self
//Setup tableView work
return tv
}()
var topic: Topic? {
didSet {
if let _ = topic {
getData()
}
}
}
override init(frame: CGRect) {
super.init(frame: frame)
//Setup views work
}
这是我的一些其他尝试:
尝试1 ,将getData()
移至init(frame: CGRect)
,但由于尚未设置getData
,因此未调用topic
。< / p>
尝试2 ,将getData()
移至layoutSubviews()
,如下所示:
override func layoutSubviews() {
if let _ = topic {
getData()
}
super.layoutSubviews()
}
但这会递归调用getData()
。
更新:
getData()
var posts = [Post]()
fileprivate func getData() {
getDataFromApi { (posts, err) in
if let err = err {
print(err)
}
if let posts = posts {
DispatchQueue.main.async {
if posts.count != 0 {
self.posts += posts
self.tableView.reloadData()
}
}
}
}
}
答案 0 :(得分:0)
如果您要在所有应用程序打开时都寻求性能,最好是在首次加载CoreData或诸如Parse Server或Firebase上的本地数据存储之类的数据后,将该数据与CoreData缓存到设备上
查询看起来像这样
->检查CoreData中所需的对象
->如果找到的对象几乎立即显示在集合单元的表格视图中
->如果没有对象从数据库加载到表视图中显示
->下次将加载的数据保存到CoreData中
CoreData Swift: How to save and load data?
如果您每次访问视图控制器时都希望提高性能,那么我会将数据存储到vc加载时的嵌套数组中
var tablesData = [[Object]]()
在前进的道路上,您可以在每次加载单元格后将它们设置为这样
tablesData[collectioncellindex] = tableobjects
然后,您可以在收集单元格上的每个tableView的后面访问类似的每个对象
let tableobject = tablesData[collectioncellindex][tableviewrow]
以第一个索引为收集单元(包含所有表数据),以第二个索引为表视图单元(具有一个表单元的数据)
您甚至还可以最初将所有数据加载到嵌套数组中,这样就不必在两次滑动之间加载数据-我想这取决于您需要加载多少数据以及哪种数据,但是如果不需要的话太长的时间可能是您更好的选择
希望这会有所帮助!
答案 1 :(得分:0)
在后台线程上调用getData()以便在下载数据时不阻塞主线程。 .userInteractive和.userInitiated都是高优先级后台线程。如果您希望下载文件简短快捷,请使用前一个,否则请使用后一个。
var topic: Topic? {
didSet {
if let _ = topic {
DispatchQueue.global(qos: .userInitiated) {
self.getData()
}
}
}
}
您可以通过添加activityIndicator来改善用户体验,并在需要时使用缓存。缓存可以帮助您暂时保留数据,这样,当用户需要再次访问数据时,您不必重新下载数据。