为啥我的collectionView中的单元格的形成速度比接收数据的方法快,因为它们的形成?

Posted

技术标签:

【中文标题】为啥我的collectionView中的单元格的形成速度比接收数据的方法快,因为它们的形成?【英文标题】:Why My cells in collectionView are formed faster than the method of receiving data, for their formation?为什么我的collectionView中的单元格的形成速度比接收数据的方法快,因为它们的形成? 【发布时间】:2022-01-01 12:46:10 【问题描述】:

在我的应用程序中,授权后,用户被带到一个屏幕,根据指定的参数显示新闻,新闻通过API传输。

在viewWillAppear方法中,触发了getUserSettings方法,其中触发了fetchNewsData方法,它用消息填充一个数组,基于这个数组形成集合单元格。该数组填充了来自数据库的实际数据,其中包含用户设置。我的代码如下:

class NewsViewController: UIViewController 
    
    let networkManager = NetworkManager()
    
    var newsArray = [NewsModel]()
    var totalResult:Int = 0
    var ref: DatabaseReference!
    
    @IBOutlet weak var collectionView: UICollectionView!
    
    @IBAction func settingsAction(_ sender: UIBarButtonItem) 
        performSegue(withIdentifier: "settingsSegue", sender: nil)
    
    
    @IBAction func unwindSegueToNewsScreen(segue: UIStoryboardSegue) 
        
        guard segue.identifier == "unwindFromSettingsSegue" else  return 
    
    
    private func getUserSettings(completion: @escaping (UserModel) -> ()) 
        guard let currentUser = Auth.auth().currentUser else  return 
        
        var user: UserModel!
        user = UserModel(user: currentUser)
        ref = Database.database().reference(withPath: "users").child(String(user.uid))
        ref.observe(.value)  snapshot in
            guard let snapshotValue = snapshot.value as? [String : String] else  return 
            user.userCountry = snapshotValue["country"]
            user.userCategory = snapshotValue["category"]
            completion(user)
        
    
    
    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
        
        getUserSettings  [weak self] user in
            self?.networkManager.fetchNewsData(forCoutry: user.userCountry ?? "us", category: user.userCategory ?? "sports")  [weak self] newsDataModel in
                
                self?.totalResult = newsDataModel.totalResults
                
                for article in newsDataModel.articles 
                    let news = NewsModel(newsTitle: article.title,
                                         urlToNewsWebSite: article.url,
                                         authorWebSiteName: article.source.name,
                                         urlToImage: article.urlToImage ?? "" )
                    
                    self?.newsArray.append(news)
                
                DispatchQueue.main.async 
                    self?.collectionView.reloadData()
                
                
            
        
    
    



extension NewsViewController: UICollectionViewDataSource 
    
    func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return newsArray.count
    
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as! NewsCell
        cell.configureCell()
        cell.initData(news: newsArray[indexPath.item])
        return cell
    

我想让用户能够在另一个屏幕上更改设置

在第二个屏幕上,用户将更新他们在数据库中的数据,当我返回新闻屏幕时,我希望表再次加载更新的数据,但是我有一个问题。

表格第一次加载数据时,触发单元格形成方法:

 func numberOfSections(in collectionView: UICollectionView) -> Int 
        return 1
    
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int 
        return newsArray.count
    
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as! NewsCell
        cell.configureCell()
        cell.initData(news: newsArray[indexPath.item])
        return cell
    

但是由于最初带有新闻的数组是空的,因此无法形成单元格。 newsArray.count // = 0

但是由于最初带有消息的数组是空的,无法形成单元格,所以启动了填充数组并重新加载单元格的方法,现在单元格形成了。但是当我从设置屏幕进入新闻屏幕时,单元格已经有数据了,因为newsArray不是空的,屏幕上会显示不相关信息的单元格。

我尝试使用 collectionView.reloadData() 更新集合,但没有帮助,我也尝试过:

 override func prepare(for segue: UIStoryboardSegue, sender: Any?) 
        guard segue.identifier == "unwindFromSettingsSegue" else  return 
        let dvc = segue.destination as! NewsViewController
        dvc.collectionView.reloadData()
    

这不起作用,因为集合只是使用进入设置屏幕之前生成的 newsArray 值更新

需要进行哪些更改才能使其正常工作?

【问题讨论】:

我认为你需要澄清这个问题。您是说最初加载一些数据,然后进入设置屏幕,返回时数据仍然存在?如果是这样,为什么您希望表在数据没有更改的情况下显示不同的数据?您需要根据新的参数集获取新数据或过滤现有数据 填充newsArray的方法,在此基础上形成单元格,在ViewWillAppear中,我想要填充NewsArray并在更新数组的基础上配置单元格的方法从设置屏幕切换回来,但会发生相反的情况。首先,根据旧数据配置单元格,然后用新数据填充数组。 【参考方案1】:

根据您发布的代码,我猜您需要先清除 newsArray,然后再将内容加载到其中。由于您的代码现在已经编写好了,因此您可以在其中添加新消息。这将导致您不断添加而不是替换那里的内容。

【讨论】:

你能告诉我怎么做吗?或许有清除细胞的方法? 又看了几遍你的回答,我明白你的意思了!谢谢,更正了代码,现在一切正常! 可能只在数组上调用removeAll()就足够了。

以上是关于为啥我的collectionView中的单元格的形成速度比接收数据的方法快,因为它们的形成?的主要内容,如果未能解决你的问题,请参考以下文章

collectionview 单元格中的阴影与 swift 中的其他单元格的行为方式不同

如何在 CollectionView iOS Swift 4 中显示不显示单元格的标题?

仅更改一个 collectionview 单元格的对象

CollectionView 中的自定义单元格重新排序行为

为啥我的 collectionview 单元格没有动画?

UICollectionView 中的多种单元格类型