I've been trying to figure out what the issue is in this code for it to throw an index out of range error. However, I am unable to understand where the issue is.
我一直试图弄清楚这个代码中的问题是什么,它会使索引超出范围错误。但是,我无法理解问题所在。
Here is the code
这是代码
import UIKit
import Alamofire
class MenuViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
let cellId = "cellId"
let headerId = "headerId"
var itemCategories: [MenuItemCategory]?
var menuItem: [MenuItem]?
override func viewDidLoad() {
super.viewDidLoad()
collectionView?.backgroundColor = .white
navigationItem.titleView = UIImageView(image: #imageLiteral(resourceName: "mooyahLabelLogo"))
collectionView?.register(MenuViewControllerCell.self, forCellWithReuseIdentifier: cellId)
collectionView?.register(MenuViewControllerHeader.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: headerId)
MenuItemCategory.fetchMenuItems { (itemCategories) in
self.itemCategories = itemCategories
self.collectionView?.reloadData()
}
}
override func numberOfSections(in collectionView: UICollectionView) -> Int {
if let count = itemCategories?.count {
print("Number of Sections: \(count)")
return count
}
return 0
}
override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as! MenuViewControllerHeader
if let categoryName = itemCategories?[indexPath.section].name {
header.categoryNameLabel.text = categoryName
}
return header
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
return CGSize(width: view.frame.width, height: 44)
}
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if let count = itemCategories?[section].items?.count {
print("Number of Items in Section: \(count)")
return count
}
return 0
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuViewControllerCell
if let category = itemCategories?[indexPath.item] {
print("Section: \(category.name!)")
if let itemsCount = category.items?.count {
for i in 0..<itemsCount {
print("Item: \(category.items?[i].name ?? "")")
cell.itemNameLabel.text = category.items?[i].name ?? ""
cell.itemDescriptionLabel.text = category.items?[i].desc ?? ""
if let price = category.items?[i].price {
cell.itemPriceLabel.text = "AED \(price)"
}
}
}
}
return cell
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: view.frame.width, height: 85)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
return 0
}
}
Here is the debugger print where it shows that my number of sections are correct as well as the number of items in section is correct. I am not sure where the issue arises from?
这是调试器打印,其中显示我的部分数量正确以及部分中的项目数是正确的。我不确定问题出在哪里?
调试器截图
2 个解决方案
#1
1
In override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell Shouldn't this line be
在override func collectionView(_ collectionView:UICollectionView,cellForItemAt indexPath:IndexPath) - > UICollectionViewCell这行不应该是
if let category = itemCategories?[indexPath.section] { .... }
Not
不
if let category = itemCategories?[indexPath.item] { .... }
#2
0
I would suggest to use a guard
to make sure that your items are available like this
我建议使用警卫来确保你的物品可以这样使用
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuViewControllerCell
guard let itemCategories = itemCategories, itemCategories.indices.contains(indexPath.item), let items = category.items else {
return cell
}
if let category = itemCategories[indexPath.item] {
print("Section: \(category.name!)")
if let itemsCount = items.count {
for i in 0..<itemsCount {
if items.indices.contains(i) {
print("Item: \(items[i].name ?? "")")
cell.itemNameLabel.text = items[i].name ?? ""
cell.itemDescriptionLabel.text = items[i].desc ?? ""
if let price = category.items?[i].price {
cell.itemPriceLabel.text = "AED \(price)"
}
}
}
}
}
return cell
}
#1
1
In override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell Shouldn't this line be
在override func collectionView(_ collectionView:UICollectionView,cellForItemAt indexPath:IndexPath) - > UICollectionViewCell这行不应该是
if let category = itemCategories?[indexPath.section] { .... }
Not
不
if let category = itemCategories?[indexPath.item] { .... }
#2
0
I would suggest to use a guard
to make sure that your items are available like this
我建议使用警卫来确保你的物品可以这样使用
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuViewControllerCell
guard let itemCategories = itemCategories, itemCategories.indices.contains(indexPath.item), let items = category.items else {
return cell
}
if let category = itemCategories[indexPath.item] {
print("Section: \(category.name!)")
if let itemsCount = items.count {
for i in 0..<itemsCount {
if items.indices.contains(i) {
print("Item: \(items[i].name ?? "")")
cell.itemNameLabel.text = items[i].name ?? ""
cell.itemDescriptionLabel.text = items[i].desc ?? ""
if let price = category.items?[i].price {
cell.itemPriceLabel.text = "AED \(price)"
}
}
}
}
}
return cell
}