为什么 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,然后再将内容加载到其中。当您现在编写代码时,您将新的新闻添加到它。这会导致你不断地添加它而不是替换那里的东西。
在我的应用中,授权后,用户被带到一个屏幕,根据指定的参数显示新闻,新闻通过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,然后再将内容加载到其中。当您现在编写代码时,您将新的新闻添加到它。这会导致你不断地添加它而不是替换那里的东西。