【问题标题】:UICollectionView - random cells are selectedUICollectionView - 随机选择单元格
【发布时间】:2019-12-14 03:07:41
【问题描述】:

我有一个水平 UICollectionView,就像 iOS 中的水平日历一样。 分页已启用但不允许MultipleSelection。

self.allowsMultipleSelection = false
self.isPagingEnabled = true

每页只有 5 个单元格。

 let cellSize =    CGSize(width: self.view.frame.width / 5 , height: 60)

CollectionView 的高度也是 60。

didSelectItemAt 将背景颜色更改为 .red 并且 didDeselectItem 将其重置为 .white

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    if let cell = cell {
        cell.backgroundColor = .red
    }
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    if let cell = cell {
        cell.backgroundColor = .white
    }
}

集合视图有多个部分和行。如果我在第一个可见页面中选择一个单元格并滚动,则会在下一个可见页面中选择随机单元格。也就是说,随机单元格在接下来的页面中是红色的。我不希望这样。我想手动选择/更改单元格的颜色。

我该如何解决这个问题?

【问题讨论】:

  • 单元格是从回收的单元格中重复使用的,您需要以某种方式保持每个单元格的状态并在 cellForRow 中分配值
  • 你能展示你的 cellForRowAt 方法吗?
  • 您需要保留您选择的索引并在cellForRow中相应地呈现它

标签: ios swift uicollectionview uicollectionviewflowlayout


【解决方案1】:

取一个类级别的变量,比如index

var index = -1

正如您所说,不允许多项选择,因此以下内容将为您完成这项工作

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    index = indexPath.item
    collectionView.reloadData()
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    let cell = collectionView.cellForItem(at: indexPath)
    if let cell = cell {
        cell.backgroundColor = indexPath.item == index ? .red :  .white
    }
}

每当用户点击任何单元格时,我们都会将位置保存在 index 变量中,然后调用 reloadData() 以通知 collectionView 更改 在cellForRowAt 中,我们检查我们选择的当前单元格是否将颜色设置为红色,否则为白色

【讨论】:

    【解决方案2】:

    不要忘记 UICollectionView 已经嵌入了重用机制,所以你应该在单元格类中直接取消选择“prepareToReuse”方法中的单元格。

    【讨论】:

      【解决方案3】:

      首先,如果你想保留多选,你必须记住你在一个数组中选择的那些,因为如果一个单元格被回收和重复使用它会丢失。为此,请使用 [IndexPath] 类型)。如果一个选定的单元格就足够了,您可以使用以下代码的非数组版本。

      var selectedItems: [IndexPath] = []
      

      然后,在单元格的cellForItemAt(:) 中重新着色:

      cell.backgroundColor = selectedItems.contains(indexPath) ? .red : .white
      

      您的didSelectItemAt 委托函数应如下所示:

      if !selectedItems.contains(indexPath) { selectedItems.append(indexPath)}
      
      collectionView.cellForItem(at: indexPath)?.backgroundColor = .red
      

      还有你的 didDeselectItemAt 委托函数:

      if let index = selectedItems.firstIndex(of: indexPath) { selectedItems.remove(at: index) }
      
      collectionView.cellForItem(at: indexPath)?.backgroundColor = .white
      

      这应该确实有效。如果我们需要进行调整,请告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多