2017-08-24 46 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 

} 
相關問題