In my application, after authorization, the user is taken to a screen that displays news according to the specified parameters, news is transmitted through the API.
in the viewWillAppear method, the getUserSettings method is triggered, in which the fetchNewsData method is triggered, which fills an array with news, based on this array, collection cells are formed. The array is filled with actual data from the database, which contains user settings. My code is below:
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
}
}
I want to give the user the ability to change settings on an additional screen
On the second screen, the user will update their data in the database, and I want the table to load the updated data again when I return to the news screen, but I have a problem.
When the table loads data for the first time, the cell formation methods are triggered:
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
}
But due to the fact that initially the array with news is empty, cells cannot be formed. newsArray.count // = 0
But due to the fact that initially the array with news is empty, the cells cannot be formed, so then the method is launched that fills the array and reloads the cells, and now the cells are formed. But when I get to the news screen from the settings screen, the cells already have data, because the newsArray is not empty, and cells with irrelevant information are displayed on the screen.
i tried to update collection using collectionView.reloadData()
but it doesn't help, also i tried this:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard segue.identifier == "unwindFromSettingsSegue" else { return }
let dvc = segue.destination as! NewsViewController
dvc.collectionView.reloadData()
}
This doesn't work because the collection is simply updated with the newsArray values that were generated before going to the settings screen
What needs to be changed to make this work correctly?
CodePudding user response:
Based on the code you posted, I'm guessing that you will need to clear the newsArray before you load content into it again. As your code is written now, you append new news to it. This would lead to you continually adding to it instead of replacing what was there.