一个视图控制器中具有不同重用单元的两个集合视图

时间:2017-11-22 01:28:21

标签: ios swift xcode uicollectionview

在我的视图控制器中,我希望有两个集合视图。尝试此操作后,我收到了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
}

}

3 个答案:

答案 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
    }
}