Hi there! I've created a sample project that shows my problem exactly. Click to download!
我创建了一个包含UICollectionViewCell
子类的应用,它包含一个ImageView
作为子视图。它还有一个包含视图的XIB文件。
当我在UICollectionViewCell
中直接嵌入UICollectionView
时使用此ViewController
时,单元格工作正常。这是包含注册单元格的代码的 WorkingViewController 的代码:
class WorkingViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
@IBOutlet weak var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let cellNib = UINib(nibName: "ImageCell", bundle: nil)
collectionView.register(cellNib, forCellWithReuseIdentifier: "ImageCell")
collectionView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func randomInt(min: Int, max: Int) -> Int {
return Int(arc4random_uniform(UInt32(max - min + 1))) + min
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as? ImageCell else {
fatalError("Could not load cell")
}
let randomNumber = randomInt(min: 1, max: 10)
cell.imageView.image = UIImage(named: "stockphoto\(randomNumber)")
return cell
}
}
现在将 Storyboard入口点移到 BuggyViewController 。此处UICollectionView
未直接嵌入。它包含在UIView
中,也包含XIB
。这是该视图的代码,包含从之前注册的单元格:
class DetailView: UIView, UICollectionViewDelegate, UICollectionViewDataSource {
@IBOutlet var contentView: UIView!
@IBOutlet weak var collectionView: UICollectionView!
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
Bundle.main.loadNibNamed("DetailView", owner: self, options: nil)
self.addSubview(self.contentView)
self.contentView.frame = self.bounds
self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
collectionView.delegate = self
collectionView.dataSource = self
let cellNib = UINib(nibName: "ImageCell", bundle: nil)
collectionView.register(cellNib, forCellWithReuseIdentifier: "ImageCell")
collectionView.register(ImageCell.self, forCellWithReuseIdentifier: "ImageCell")
collectionView.reloadData()
}
func randomInt(min: Int, max: Int) -> Int {
return Int(arc4random_uniform(UInt32(max - min + 1))) + min
}
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 100
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImageCell", for: indexPath) as? ImageCell else {
fatalError("Could not load cell")
}
let randomNumber = randomInt(min: 1, max: 10)
cell.imageView.image = UIImage(named: "stockphoto\(randomNumber)")
return cell
}
}
但是这会导致DetailView第55行出错:
线程1:致命错误:在展开时出乎意料地发现nil 可选值
所以这里单元格的imageView
突然变为零,这让我觉得我在注册单元格或实例化时做错了。但我无法解决它。
答案 0 :(得分:2)
您应该删除注册单元类的行:
collectionView.register(ImageCell.self, forCellWithReuseIdentifier: "ImageCell")
确实,您已经在Nib中定义了您的单元格,并应通过方法func register(_ nib: UINib?, forCellWithReuseIdentifier identifier: String)
进行注册。通过cellClass方法注册它将返回nil。
正如Apple医生所述:
如果您以前使用相同的重用注册了类或nib文件 标识符,您在cellClass参数中指定的类将替换 旧条目。如果需要,可以为cellClass指定nil 从指定的重用标识符中取消注册该类。
这解释了为什么你没有。