实现第二个UICollectionView时出错:无法退出types视图:标识符为xxxx的UICollectionElementKindCell – 必须注册

这个问题是对上一个问题的一个后续。

我已经实现了一个UICollectionView,但是在实现第二个时无法运行该项目。 死亡的地方在哪里

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

我首先开始build立原型单元。 我有一个左侧和右侧的集合视图,每个cellLeftcellRight中的单元格分别存储在常量reuseIdentifierLeftreuseIdentifierRight中 。 (在常量中没有额外的空间 – 在其他答案中的常见问题,检查。)事情崩溃的声明是

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

错误消息是

***终止应用程序由于未捕获的exception“NSInternalInconsistencyException”,原因:'不能出队types的视图:UICollectionElementKindCell与标识符cellRight – 必须注册标识符的一个笔尖或类或连接故事板中的原型单元格'

明显的失败点是没有正确注册单元格和/或标签,虽然我已经经历了所有可能的做法,我可以想到,似乎没有任何帮助。 ( 左边的集合视图在项目中唯一的CollectionView中工作的很好,所以我想我知道如何正确地把事情搞定,但是当事情初始化的时候,右边的是先初始化的,不知道左边是否会像这样,是否失败。)

我花了几个小时的时间检查事情是否已经联系起来,而且我可以告诉他们的确是这样。 把它拿出来,把它放回去,确保它在那里,再次运行,同样的崩溃。

我的工作截图: 单元+标签,属性和连接检查器的屏幕截图

码:

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 // ie 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! } 

我完全是在智慧的结尾,查看了各种堆栈交换文章,并尝试了所有可以find的东西,但没有任何东西似乎改变了崩溃。 我是否错过了一些简单而明显的细胞和/或标签如何互相连接? 感谢任何可以提供的帮助 – 这将是非常感谢!

摆脱

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

并改变你的出队

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

对于左右集合视图

您在collectionViewRight.register(UICollectionViewCell.self, forCellWithReuseIdentifier: collectionViewRightIdentifier)注册的标识符是reuseIdentifier,不应该是一个单独的标识符

也将正在为每个单元格注册的类更改为适当的,例如

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

是否有一个原因,你使用2套重用标识符? collectionViewLeftIdentifierreuseIdentifierLeft意味着什么?

您正在使用collectionViewLeftIdentifier注册您的单元,但是您正在使用reuseIdentifierLeft出列。 这似乎有点混乱。

从你的截图判断,你的标识符应该是cellLeft ,应该在reuseIdentifierLeft下。