[英]Collection view doesn't update
我在分段控制中有 4 個類別。 當我按下其中一個時,集合視圖應顯示特定類別的產品。 但是,集合視圖不是重用單元格並僅顯示新項目,而是顯示舊項目,最后添加帶有新項目的新單元格。
使用 reloadData() 的合適位置在哪里。 或者,也許我錯過了什么?
這是我的代碼
private lazy var segmentedControl: UISegmentedControl = {
var control = UISegmentedControl(items: ["All", "Men", "Women", "Jewelery", "Electro"])
control.selectedSegmentTintColor = .black
control.setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected)
control.tintColor = .white
control.selectedSegmentIndex = 0
control.addTarget(self, action: #selector(segmentChanged(_ :)), for: .valueChanged)
return control
}()
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
networkManager.delegate = self
setupMainStackView()
setupCollectionView()
networkManager.loadProducts(category: .all)
performSearch()
}
func performSearch() {
if let category = NetworkManager.Category(rawValue: segmentedControl.selectedSegmentIndex) {
networkManager.loadProducts(category: category)
collectionView.reloadData()
}
// collectionView.reloadData()
}
@objc func segmentChanged(_ sender: UISegmentedControl) {
performSearch()
}
// MARK: - 數據源擴展 MainViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return productResults.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MainViewCollectionViewCell.identifier, for: indexPath) as! MainViewCollectionViewCell
let listOfProduct = productResults[indexPath.row]
cell.configure(for: listOfProduct)
return cell
}
}
這就是我搜索類別的方式
enum Category: Int {
case all = 0
case menSClothing = 1
case womenSClothing = 2
case electronics = 3
case jewelery = 4
var type: String {
switch self {
case .all: return ""
case .menSClothing: return "category/men's%20clothing"
case .womenSClothing: return "category/women's%20clothing"
case .electronics: return "category/electronics"
case .jewelery: return "category/jewelery"
}
}
}
private func fakeStoreURL(category: Category) -> URL {
let kind = category.type
let url = URL(string: "https://fakestoreapi.com/products/" + "\(kind)")
return url!
}
func loadProducts(類別:類別){
let url = fakeStoreURL(category: category)
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print(error)
return
}
guard let data = data else { return }
do {
var products = try JSONDecoder().decode([Product].self, from: data)
products = self.parse(data: data)
print(products)
DispatchQueue.main.async {
self.delegate?.didSendProductData(self, with: products)
}
} catch {
print(error)
}
}.resume()
}
問題就在這里
networkManager.loadProducts(category: category)
collectionView.reloadData()
loadProducts
是一個異步方法,並且集合的重新加載發生在網絡數據返回之前,因此您需要一個完成
func loadProducts(category: Category,completion:@escaping([Product]? -> ())) {
let url = fakeStoreURL(category: category)
URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print(error)
completion(nil)
return
}
guard let data = data else { return }
do {
var products = try JSONDecoder().decode([Product].self, from: data)
products = self.parse(data: data)
print(products)
DispatchQueue.main.async {
completion(products)
}
} catch {
print(error)
completion(nil)
}
}.resume()
}
然后
networkManager.loadProducts(category: category) { [weak self] products in
guard let products = products else { return }
self?.productResults = products
self?.collectionView.reloadData()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.