在我的视图控制器中,我希望有两个集合视图。尝试此操作后,我收到了Sigabrt错误,我的应用程序崩溃了。我预测问题是因为我将这些集合视图的数据源分配给self。我错了,这是我的代码:
在视图中加载,我设置了集合视图的数据源:
@IBOutlet var hashtagCollectionView: UICollectionView!
@IBOutlet var createCollectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
createCollectionView.dataSource = self
hashtagCollectionView.dataSource = self
}
然后我为UICollectionViewDataSource创建一个扩展
extension CategoryViewController: UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
var returnValue = 0
if collectionView == hashtagCollectionView {
// Return number of hashtags
returnValue = hashtags.count
}
if collectionView == createCollectionView {
// I only want 3 cells in the create collection view
returnValue = 3
}
return returnValue
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
var return_cell: UICollectionViewCell
// Place content into hashtag cells
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashtagCell", for: indexPath) as! TrendingTagsCollectionViewCell
cell.hashtagText = hashtags[indexPath.row]
// Place content in creators cell
let createCell = collectionView.dequeueReusableCell(withReuseIdentifier: "createCell", for: indexPath) as! CreateCollectionViewCell
createCell.text = creators[indexPath.row]
createCell.image = creatorImages[indexPath.row]
// Is this the right logic?
if collectionView == hashtagCollectionView {
return_cell = cell
} else {
return_cell = createCell
}
return return_cell
}
}
答案 0 :(得分:4)
由于if
中的collectionView(_:cellForItemAt:)
声明并未覆盖足够的理由,因此崩溃了。
虽然你是对的,你需要根据收集视图的要求返回不同的单元格,但是你不能使用不同的标识符两次调用dequeueReusableCell(withReuseIdentifier:for:)
。由于您同时询问相同的集合视图,因此很可能其中一个标识符未在该集合视图中注册。
相反,您应该展开if
以涵盖该方法的全部内容:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == hashtagCollectionView {
// Place content into hashtag cells
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashtagCell", for: indexPath) as! TrendingTagsCollectionViewCell
cell.hashtagText = hashtags[indexPath.row]
return cell
} else if collectionView == createCollectionView {
// Place content in creators cell
let createCell = collectionView.dequeueReusableCell(withReuseIdentifier: "createCell", for: indexPath) as! CreateCollectionViewCell
createCell.text = creators[indexPath.row]
createCell.image = creatorImages[indexPath.row]
return cell
} else {
preconditionFailure("Unknown collection view!")
}
}
这只会尝试将单元格出列一次,具体取决于要查询的集合视图,并将返回的单元格强制转换为正确的类。
N.B。这种方法可以使用一段时间,但从长远来看,您可以获得非常长的UICollectionViewDataSource方法实现,所有这些都包含在一系列if
语句中。可能值得考虑将您的数据源分成不同的小类。
答案 1 :(得分:1)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashtagCell", for: indexPath) as? TrendingTagsCollectionViewCell {
cell.hashtagText = hashtags[indexPath.row]
return cell
}
if let createCell = collectionView.dequeueReusableCell(withReuseIdentifier: "createCell", for: indexPath) as? CreateCollectionViewCell {
createCell.text = creators[indexPath.row]
createCell.image = creatorImages[indexPath.row]
return createCell
}
return UICollectionViewCell() // or throw error here
}
答案 2 :(得分:0)
我认为您的代码在重用单元格时会以nil崩溃
你应该像这样测试cellForItemAt
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if collectionView == hashtagCollectionView {
// Place content into hashtag cells
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "hashtagCell", for: indexPath) as! TrendingTagsCollectionViewCell
cell.hashtagText = hashtags[indexPath.row]
return cell
} else {
// Place content in creators cell
let createCell = collectionView.dequeueReusableCell(withReuseIdentifier: "createCell", for: indexPath) as! CreateCollectionViewCell
createCell.text = creators[indexPath.row]
createCell.image = creatorImages[indexPath.row]
return createCell
}
}