我在分段控制中有 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 clothing"
case .womenSClothing: return "category/women's clothing"
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()
}
uj5u.com熱心網友回復:
問題就在這里
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()
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/496747.html
標籤:IOS 迅速 uicollectionview uikit uicollectionviewcell
