2017-01-13 4 views
0

この問題にさまざまな方法で対処しようとしています。 「NSInvalidArgumentException」、理由: 'インデックス0のセクションのインデックス3でノーオブジェクトの それはクラスAppDelegateで発生:UIResponder ...UICollectionCellの最後のセルに「新規追加」ボタンを追加します。 (CoreData)

は私のコードは

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

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! CollectionCell 
    configureCell(cell: cell, indexPath: indexPath) 

    var numberOfItems = self.collectionView(self.collectionView, numberOfItemsInSection: 0) 

    if (indexPath.row == numberOfItems - 1) { 

     var addCellButton = UIButton(frame: cell.frame) 
     addCellButton.setTitle("Add", for: UIControlState.normal) 
     cell.addSubview(addCellButton) 
    } 
    return cell 
} 

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

    if let sections = controller.sections { 
     let sectionInfo = sections[section] 
     return sectionInfo.numberOfObjects + 1 
    } 
    return 0 
} 

func numberOfSections(in collectionView: UICollectionView) -> Int { 
    if let sections = controller.sections { 
     return sections.count 
    } 
    return 0 
} 
ある 現在の実装では私にエラーを与えます

アドバイスはありますか?

+0

を、それはあなたのcollectionViewのように思えます複数のセクションがあり、すべてのセクションには追加ボタンがあります。この仮定は正しいですか?または、セクションの1つだけに追加ボタンが必要ですか? – Zhang

+0

@ Zhangセクションのみ。 1つのセクションの最後にボタンを追加します。 –

答えて

2

でそれを返す:あなたのコードから

import UIKit 

class ViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource { 

    var collectionView:UICollectionView! 
    var items = ["Apple", "Banana", "Orange", "Watermelon", "Coconut"] 


    ... 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

     // ------------------------------------------ 
     // +1 here for the extra add button 
     // at the bottom of the collection view 
     // ------------------------------------------ 
     return items.count + 1 
    } 

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

     // -------------------------------- 
     // IndexPath row vs Items Count 
     // -------------------------------- 
     // [0] = Apple 
     // [1] = Banana 
     // [2] = Orange 
     // [3] = Watermelon 
     // [4] = Coconut 
     // 
     // [5] = special cell 
     // 
     // --------------------------------- 
     let cellID = indexPath.row < items.count ? "normalCell" : "specialCell" 

     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellID, for: indexPath) 

     setupCell(cell: cell, indexPath: indexPath, type: cellID) 

     return cell 
    } 

    func setupCell(cell: UICollectionViewCell, indexPath: IndexPath, type: String) { 
     switch(type) { 
     case "normalCell": 
      setupFruitCell(cell: cell as! FruitCell, indexPath: indexPath) 
     case "specialCell": 
      setupSpecialCell(cell: cell as! SpecialCell, indexPath: indexPath) 
     default: 
      break 
     } 
    } 

    func setupFruitCell(cell: FruitCell, indexPath: IndexPath) { 
     cell.label.text = items[indexPath.row] 
    } 

    func setupSpecialCell(cell: SpecialCell, indexPath: IndexPath) { 
     cell.btnAdd.addTarget(self, action: #selector(addButtonTapped), for: UIControlEvents.touchUpInside) 
    } 

    func addButtonTapped(sender: UIButton) { 
     print("Show UI to add new fruit") 
    } 
} 
+0

2つのセル識別子を作成しようとしました。 エラーは持続しました。 このエラーをさらに調査する方法はありますか?何か提案はありますか? –

+0

あなたのロジックに従うように私のコードを書き換え、別の "configureCell"メソッドを実装しました。 まだ同じエラーがありました:インデックス0のセクションのインデックス3のオブジェクトがありません。 –

+0

データソースを印刷するとどうなりますか?たとえば、上記のコードでは、 'return items.count + 1'の上に' print( "Items = \(items)") 'を追加して、実際に配列にあったものを出力します。どちらの方法でも、表示されているエラーは、データソースに4番目の要素(インデックス3)がなく、存在しない要素にアクセスしようとしているためエラーです。 – Zhang

1

セルにビューを追加して混乱させないでください。セルはスクリーンから外れるとリサイクルされます(dequeueReusableCellが呼び出された理由)。余分な視点を取り除いてから再利用する準備ができていない限り、彼らはセルに留まり、何度も何度も追加されます。代わりに、2つの他のオプションがあります。

1)インタフェースビルダーで2番目のcollectionViewCellを独自のクラスとreuseIdentifierで作成し、このセルのインスタンスを最後のセルに対してのみデキューします。

2)この2つの別々のセルデキューするようにあなたはそれを書くことができフッタービューのボタン部分を作り、viewForSupplementaryElementOfKind

+0

cellForItemAt:の2つの異なるセルをデキューしようとしています。 "If"ステートメントを構造化して最後のセルと最後のセルをターゲットにする方法を教えてください。 –

+0

"numberOfItems(inSection :)"のセクション内のアイテムの計算数 条件の実行:indexPath.item <= numberOfItems - 1 "'インデックス0のセクションのインデックス3にオブジェクトがありません。 残念ながら、 "Add" btnを別の場所に作成することに切り替えました。 –

関連する問題