【问题标题】:Two Collection Views with Different Reuse Cells in One View Controller一个视图控制器中具有不同重用单元的两个集合视图
【发布时间】:2017-11-22 01:28:20
【问题描述】:

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

}

【问题讨论】:

    标签: ios swift xcode uicollectionview


    【解决方案1】:

    这是崩溃的,因为您在 collectionView(_:cellForItemAt:) 中的 if 语句没有完全覆盖足够的基础。

    虽然您需要根据集合视图的要求返回不同的单元格是对的,但您不能使用类似的不同标识符两次调用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!")
        }
    }
    

    这只会尝试使单元格出队一次,具体取决于所询问的集合视图,并将返回的单元格转换为正确的类。

    注意这种方法暂时有效,但从长远来看,您可以获得很长的 UICollectionViewDataSource 方法实现,所有这些都包含在一系列if 语句中。可能值得考虑将您的数据源分成单独的较小类。

    【讨论】:

      【解决方案2】:
      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
          }
      

      【讨论】:

        【解决方案3】:

        我认为你的代码在重用单元格时会以零崩溃

        你应该像这样测试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
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2016-07-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多