首页 > 解决方案 > Swift:UICollectionViewCell 只获取一次数据

问题描述

我有一个水平滚动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

尝试 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()
                }
            }        
        }
    }
}

标签: iosswift

解决方案


如果您正在寻找所有应用程序打开的性能,最好在首次加载后使用 CoreData 将此数据缓存到设备(或类似 Parse Server 或 Firebase 上的本地数据存储)

查询看起来像这样

--> 检查 CoreData 是否有您需要的对象

--> 如果找到的对象会立即显示在集合单元格的 tableview 中

--> 如果没有从数据库加载对象以显示在 tableview 上

--> 将加载的数据保存到 CoreData 以备下次使用

CoreData Swift:如何保存和加载数据?

如果您只是在每次访问视图控制器时都在寻找改进的性能,我会在加载数据时将数据存储到 vc 上的嵌套数组中

var tablesData = [[Object]]()

在前进的路上,您可以在每次单元加载后像这样设置它们

tablesData[collectioncellindex] = tableobjects

然后,您可以在返回集合单元格上的每个 tableView 的路上访问每个对象

let tableobject = tablesData[collectioncellindex][tableviewrow]

将第一个索引视为集合单元格(包含所有表格数据),将第二个索引视为表格视图单元格(包含一个表格视图单元格的数据)

您甚至可以最初将所有数据加载到嵌套数组中,这样就不必在两次滑动之间加载 - 我想这取决于您需要加载多少数据以及加载哪种数据,但如果不需要太长时间可能是你更好的选择

希望这可以帮助!


推荐阅读