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

Why My cells in collectionView are formed faster than the method of receiving data, for their formation?

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

传输

在viewWillAppear方法中,触发了getUserSettings方法,其中触发了fetchNewsData方法,将新闻填充到一个数组中,根据这个数组,形成collection个单元格。该数组填充了来自数据库的实际数据,其中包含用户设置。我的代码如下:

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
    }
}

我想让用户能够在附加屏幕上更改设置

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

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

 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
    }

但是由于news的数组一开始是空的,所以无法形成cell。 newsArray.count // = 0

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

我尝试使用 collectionView.reloadData() 更新 collection 但它没有帮助,我也试过这个:

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

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

需要更改什么才能使其正常工作?

根据您发布的代码,我猜您需要先清除 newsArray,然后再将内容加载到其中。当您现在编写代码时,您将新的新闻添加到它。这会导致你不断地添加它而不是替换那里的东西。