2016-11-24 4 views
0

この質問はthis previous questionのフォローアップです。2番目のUICollectionViewを実装する際にエラーが発生しました:種類のビューをデキューできませんでした:識別子xxxxのUICollectionElementKindCell - 登録が必要です

私は1 UICollectionViewを実装しましたが、私は 1を実装したときに実行するプロジェクトを取得することはできません。物事が死んでいるところは、

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

ここで私は最初にプロトタイプのセルを設定し始めます。私はreuseIdentifierRightそれぞれ命名cellLeftcellRightのセルで、左右のコレクションビューを持っている、と定数に保存されているものの名​​前reuseIdentifierLeft。物事のクラッシュが

let rightCell = collectionView.dequeueReusableCell(withReuseIdentifier: 
    reuseIdentifierRight, for: indexPath as IndexPath) as! 
    MyRightCollectionViewCell 

エラーメッセージが

である - (定数の余分なスペース。他の回答に共通する問題は、そのためにチェックしない)の文***のためにアプリを終了キャッチされない例外「NSInternalInconsistencyException」、理由:「種類のビューをデキューできませんでした:識別子cellRightとUICollectionElementKindCell - 識別子のためのペン先やクラスを登録したり、ストーリーボードでプロトタイプセルを接続する必要があります」

明白な失敗のポイントは、セルやラベルを正しく登録していませんが、私が考えることができるすべての可能性がありましたが、何も助けに見えるものはありません。 (コレクションビューのの左にのサイドが正常に機能していたので、プロジェクトの唯一のCollectionViewだったので、正しくフックする方法を知っていると思っていました。しかし、物事を初期化するときは、このように左側が失敗するかどうかはわかりません)

私は何かが繋がっていることを確認するのに数時間を費やしています。これを取り出して、一緒に戻して、それがすべてそこにあることを確認し、再び同じクラッシュを実行します。私の仕事の

スクリーンショット: Screenshot of the Cell + Label, Attributes & Connections inspectors

コード:

ViewController.swift

import UIKit 

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { 

var collectionViewLeft: UICollectionView!       
var collectionViewRight: UICollectionView! 

let collectionViewLeftIdentifier = "CollectionViewLeftCell" 
let collectionViewRightIdentifier = "CollectionViewRightCell" 

override func viewDidLoad() { 
    super.viewDidLoad() 

    let layoutLeft = UICollectionViewFlowLayout() 
    layoutLeft.itemSize = CGSize(width: 100, height: 100) 

    let layoutRight = UICollectionViewFlowLayout() 
    layoutRight.itemSize = CGSize(width: 100, height: 100) 

    collectionViewLeft = UICollectionView(frame: self.view.frame, collectionViewLayout: layoutLeft) 
    collectionViewRight = UICollectionView(frame: self.view.frame, collectionViewLayout: layoutRight) 

    collectionViewLeft.delegate = self 
    collectionViewRight.delegate = self 

    collectionViewLeft.dataSource = self 
    collectionViewRight.dataSource = self 

    collectionViewLeft.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewLeftIdentifier) 
    collectionViewRight.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewRightIdentifier) 

    self.view.addSubview(collectionViewLeft) 
    self.view.addSubview(collectionViewRight) 

    print("Both subviews added ok.")  // this DOES print. 
} 

let reuseIdentifierLeft = "cellLeft" 
let reuseIdentifierRight = "cellRight" 

var itemsRight = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"] 
var itemsLeft = ["10", "20", "30", "40", "50", "60"] 


// MARK: - UICollectionViewDataSource protocol 

// tell the collection view how many cells to make 
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

    if collectionView == self.collectionViewLeft { 
      return self.itemsLeft.count 
    } else if collectionView == self.collectionViewRight { 
      return self.itemsRight.count 
    } else { 
     print("This is very bad") 
     assert(false, "Passed collectionView is neither collectionViewLeft nor collectionViewRight -- ruh roh!") 
     return 0 
    } 
} 

// make a cell for each cell index path 
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

    if collectionView == self.collectionViewLeft { 

     print("Attempting Left...")   // not observed -- 'right' is evidently getting called first. 
     // get a reference to our storyboard cell 
     let leftCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierLeft, for: indexPath as IndexPath) as! MyCollectionViewCell 
     print("hit let leftCell = collectionView.dequeue...") 
     leftCell.myLeftLabel.text = self.itemsLeft[indexPath.item] 
     leftCell.backgroundColor = UIColor.red // make cell more visible in our example project 
     return leftCell 
    } else if collectionView == self.collectionViewRight { 

     print("Attempting Right... reuseIdentifierRight='" + reuseIdentifierRight + "'")  // this prints: "Attempting Right... reuseIdentifierRight='cellRight'" which looks okay. 

     let rightCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierRight, for: indexPath as IndexPath) as! MyRightCollectionViewCell 


     //    ^
     //     /|\ 
     //    /| \ 
     //     | 
     //     | 
     // 
     //    Dies here. 
     // *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'could not dequeue a view of kind: UICollectionElementKindCell with identifier cellRight - must register a nib or a class for the identifier or connect a prototype cell in a storyboard' 

     // attempted, no help: 
     //    let rightCell = collectionView.dequeueReusableCell(withReuseIdentifier: self.reuseIdentifierRight, for: indexPath as IndexPath) as! MyRightCollectionViewCell 
     // i.e. adding "self" into "self.reuseIdentifierRight" 


     print("Successfully hit 'let rightCell = collectionView.dequeue...'") // does NOT print. 

     // Use the outlet in our custom class to get a reference to the UILabel in the cell 
     rightCell.myRightLabel.text = self.itemsRight[indexPath.item] 
     rightCell.backgroundColor = UIColor.green 
     return rightCell 
    } else { 
     print("This is very bad") 
     assert(false, "Passed collectionView is neither collectionViewLeft nor collectionViewRight -- ruh roh!") 
     // won't actually execute the following, but to keep the compiler happy... 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifierLeft, for: indexPath as IndexPath) as! MyCollectionViewCell 
     return cell 
    } 
} 

// MARK: - UICollectionViewDelegate protocol 

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { 

    // handle tap events 

    if collectionView == self.collectionViewLeft { 
     print("You tapped cell #\(indexPath.item) on the LEFT!") 
    } else if collectionView == self.collectionViewRight { 
     print("You tapped cell #\(indexPath.item) on the RIGHT!") 
    } else { 
     print("This is very bad") 
     assert(false, "Passed collectionView is neither collectionViewLeft nor collectionViewRight -- ruh roh!") 
    } 
} 
} 

MyCollectionViewCell.swift

import UIKit 

class MyCollectionViewCell: UICollectionViewCell { 
    @IBOutlet weak var myLeftLabel: UILabel! 
} 

MyRightCollectionViewCell.swift

import UIKit 

class MyRightCollectionViewCell: UICollectionViewCell {  
    @IBOutlet weak var myRightLabel: UILabel! 
} 

私は&は私が見つけることができるそれらのすべてを試したが、何もクラッシュだ内容を変更するようだ様々なスタック交換記事を見た、ここでウィットの終わりに、絶対にしています。お互いにどのようにセルやラベルを張っておく必要があるのか​​、わかりやすいものがありますか?&ご提供いただけるお手伝いをいただき、ありがとうございます。

+0

私が持っている根本的な質問は、ストーリーボードやプログラムによるUIの作成を使いたいのですか?あなたはストーリーボードのスクリーンショットを表示しましたが、あなたのコードはそれを使用していません。あなたがストーリーボードを使用している場合、クラスの登録はすべて – Paulw11

+0

@ Paulw11 Storyboardsになります。絶対に。物事が進むと、ストーリーボードが無視されていることが明らかです(つまり、左は「左」、右は「右」、中央は黄色のスペース)。しかし、2番目のCollectionViewをオリジナルのストーリーボード版のものに入れた後、エラーが「無限のレイアウトで初期化する必要があります」というエラーが発生したときに、登録したものになった。私は "collectionViewLeft.register"とself.view.addSubview(collectionViewLeft)の行を削除するだけですか、それ以上のことはありますか? – ConfusionTowers

+0

'super.viewDidLoad'以外の' viewDidLoad'でそのコードをすべて削除し、 '@IBOutlet weak var collectionViewLeft:UICollectionView!'と '@IBOutlet weak var collectionViewRight:UICollectionView! 'を宣言してコレクションビューを@ Interface BuilderのIBOutlet – Paulw11

答えて

2

let reuseIdentifierLeft = "cellLeft" 
let reuseIdentifierRight = "cellRight" 

を取り除くと、左右のコレクションビュー

あなたは collectionViewRight.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewRightIdentifier)に登録識別子がreuseIdentifierで

、そしてはずの両方について

let rightCell = collectionView.dequeueReusableCell(withReuseIdentifier: collectionViewRightIdentifier, for: indexPath as IndexPath) as! MyRightCollectionViewCell 

にあなたのデキューを変えなさい別の識別子にする

はまた、各セルに登録されているクラスを適切なものに変更します。

collectionViewLeft.register(MyCollectionViewCell.self, forCellWithReuseIdentifier: collectionViewLeftIdentifier) 
collectionViewRight.register(MyRightCollectionViewCell.self, forCellWithReuseIdentifier: collectionViewRightIdentifier) 
+0

それはうまくいった - 私が得ていたエラーを取り除いた!ありがとうございました!!!ただし、同じ手順でエラーが発生しました。「型 'UICollectionViewCell(0x10e904e98)の値を' twoCollectionViews.MyRightCollectionViewCell '(0x10cc8d730)にキャストできませんでした。何かご意見は?あなたの 'collectionViewRight.register'には – ConfusionTowers

+0

があり、左側のクラスは同じクラスを登録しているようですが、これは意図的なのでしょうか?それは識別子のための間違ったタイプのセルを待ち行列に入れているように思えます。私の編集された答えを参照してください。 – Fonix

+0

左側のコレクションビューのセルは右側のコレクションビューのセルと同じではありません。この時点では、ラベルとはちょうど異なる名前ですが、後で、左側と右側のセルの差が大きくなります。私はUICollectionViewをベースにしていますが、左は別のクラスになっていると考えましたが、別々にすることを意図しています。私はcollectionView ___。register()ステートメントでそれを取得しましたか? – ConfusionTowers

0

2組の再使用識別子を使用する理由はありますか? collectionViewLeftIdentifierreuseIdentifierLeftは同じものを意味していますか?

collectionViewLeftIdentifierでセルを登録していますが、reuseIdentifierLeftでデキューしています。ちょっと混乱しているようです。

あなたのスクリーンショットで判断すると、あなたの識別子はcellLeftであるはずです(reuseIdentifierLeft)。

+0

私は、それが当てはまらないときに2つの識別子が分かれていると考えて、私の混乱/誤解の一部であったと思います。 – ConfusionTowers

関連する問題