2017-01-02 65 views
0

我有兩個不同的單元格類,我試圖使PayNowCell類的第一個路徑,讓它保持顯示。而其他單元是類CheckOutCell。現在問題出在我func numberofitemsinsection。目前我正在使用return checkout.count,但在視圖加載時它丟失了PayNowCell。如果我讓checkout返回checkout.count + 1總是可以使用PayNowCell;我的程序崩潰給我錯誤索引越界。數組簽出是一個全局變量。有人可以解釋爲什麼並提供修復嗎?一直卡在這一點上。代碼如下。UICollection NumberOfItemsInSections問題與添加一個常量到變數

class CheckoutController: UICollectionViewCell, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout { 

    var inventoryTabController: InventoryTabController? 

    override init(frame: CGRect){ 
     super.init(frame: frame) 
     setupViews() 

     NotificationCenter.default.addObserver(forName: .arrayValueChanged, object: nil, queue: OperationQueue.main) { [weak self] (notif) in 
      self?.collectionView.reloadData() 
     } 

    } 

    deinit { 
     NotificationCenter.default.removeObserver(self) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    func loadItems() -> [Item]? { 
     return NSKeyedUnarchiver.unarchiveObject(withFile: Item.ArchiveURL.path) as? [Item] 
    } 

    func saveItems() { 
     let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(checkout, toFile: Item.ArchiveURL.path) 
     if !isSuccessfulSave { 
      print("Failed to save items...") 
     } 
    } 

    func addItem(item: Item) { 
     items.append(item) 
     collectionView.reloadData() 
    } 

    func editItem(item: Item, index: Int) { 
     items[index] = item 
     collectionView.reloadData() 
    } 

    func prepare(for segue: UIStoryboardSegue, sender: Any?) { 
     // Identify which segue is occuring. 
     if segue.identifier == "ShowDetail" { 
      let itemDetailViewController = segue.destination as! AddItemController 

      // Get the cell that generated this segue. 
      if let selectedItemCell = sender as? InventoryCell { 
       let indexPath = collectionView.indexPath(for: selectedItemCell)! 
       let selectedItem = items[indexPath.row] 
       itemDetailViewController.item = selectedItem 
      } 
     } 
     else if segue.identifier == "AddItem" { 
      print("Adding new meal.") 
     } 
    } 

    lazy var collectionView: UICollectionView = { 
     let layout = UICollectionViewFlowLayout() 
     let cv = UICollectionView(frame: .zero, collectionViewLayout: layout) 

     cv.dataSource = self 
     cv.delegate = self 

     cv.backgroundColor = UIColor.rgb(r: 247, g: 247, b: 247) 
     return cv 
    }() 

    let cellId = "cellId" 
    let paynow = "paynow" 
    func setupViews() { 
     backgroundColor = .brown 

     addSubview(collectionView) 

     addConstraintsWithFormat("H:|[v0]|", views: collectionView) 
     addConstraintsWithFormat("V:|[v0]|", views: collectionView) 
     collectionView.indicatorStyle = UIScrollViewIndicatorStyle.white 

     collectionView.register(PayNowCell.self, forCellWithReuseIdentifier: paynow) 

     collectionView.register(CheckoutCell.self, forCellWithReuseIdentifier: cellId) 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return checkout.count //init number of cells 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

     if indexPath.item == 0 { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "paynow", for: indexPath) as! PayNowCell //init cells 
     return cell 
     }else{ 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CheckoutCell //init cells 
     print("Printing this \(checkout.count)") 
     cell.item = checkout[indexPath.item] 
     return cell 
     } 

    } 

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 
     //let item = items[indexPath.item] 
     //inventoryController?.showItemDetailForItem(item: item, index: indexPath.item) 
     print("selected") 
     print(indexPath.item) 
     collectionView.reloadData() 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     if indexPath.item == 0 { 
      return CGSize(width:frame.width, height: 100) //each cell dimensions 
     }else{ 
      return CGSize(width:frame.width, height: 150) //each cell dimensions 
     } 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 
     return 0 
    } 

回答

1

這是更好地重新安排你的收藏以期有2個部分:

  1. 節0:PayNow細胞(僅1個單元)
  2. 第1部分:結帳細胞(使用Google Checkout的數組列表)

然後您對indexPath.item問題沒有任何困惑。

func numberOfSections(in collectionView: UICollectionView) -> Int { 
    return 2 
} 

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
    return section == 0 ? 1 : checkout.count 
} 

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

    if indexPath.section == 0 { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "paynow", for: indexPath) as! PayNowCell //init cells 
     return cell 
    } else { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) as! CheckoutCell //init cells 
     print("Printing this \(checkout.count)") 
     cell.item = checkout[indexPath.item] 
     return cell 
    } 

} 
+0

完美的解決方案。非常感謝! –

0

您需要從您的cellForRow函數中減去1。由於您正在添加PayNowCell,因此您正在添加一個額外的indexPath,但目前,您正在使用dataSource函數給出的默認indexPath。該指數總是比您的物品數量高一個。通過從indexPath中減去1,您將重新與您的itemsArray同步,同時考慮到PayNowCell。

cell.item = checkout[indexPath.item - 1]