2017-08-24 48 views
0

我一直在试图找出哪些问题是在此代码为它抛出一个索引超出范围的错误。但是,我无法理解问题出在哪里。的CollectionView致命错误:超出范围的索引

下面是代码

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 
    } 

} 

这里是调试器打印它表明我的段数是否正确,以及项目的节数是正确的。我不确定问题来自哪里?

Debugger screenshot

+1

也许不相关,但将可选的具体集合视图控制器的数据源数组声明为无意义。您可以避免使用很多可选的绑定/可选链,并且代码的可读性更好。 – vadian

+0

@ oalansari82很难测试你的代码更好的把断点和检查流程。 –

+0

@TusharSharma我已经和这条线是什么原因导致 '?如果让类别= itemCategories [indexPath.item]' – oalansari82

回答

1

在覆盖FUNC的CollectionView(_的CollectionView:UICollectionView,cellForItemAt indexPath:IndexPath) - > UICollectionViewCell 应该不是这一行是

if let category = itemCategories?[indexPath.section] { .... } 

if let category = itemCategories?[indexPath.item] { .... } 
+0

这让它工作..我错过了那一个 – oalansari82

0

我会建议使用guard,以确保您的项目提供这样的

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 

} 
相关问题