简体   繁体   English

UICollectionView-选择随机单元格

[英]UICollectionView - random cells are selected

I have a Horizontal UICollectionView like the horizontal Calender in iOS. 我有一个水平UICollectionView,就像iOS中的水平日历。 Paging is enabled but not allowsMultipleSelection. 分页已启用,但不允许MultipleSelection。

self.allowsMultipleSelection = false
self.isPagingEnabled = true

There are only 5 cells per page. 每页只有5个单元格。

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

CollectionView's height is also 60. CollectionView的高度也是60。

didSelectItemAt change background color to .red and didDeselectItem resets it to .white . didSelectItemAt改变背景颜色.reddidDeselectItem重置它。白

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

The collection view has multiple sections and rows. 集合视图具有多个部分和行。 If I select a cell in the first visible page and scroll, random cells are selected in the next visible pages. 如果我在第一个可见页面中选择一个单元格并滚动,则会在下一个可见页面中选择随机单元格。 That is to say random cells are red in the next pages. 也就是说,下一页中的随机单元格为红色。 I do not want this to be so. 我不希望这样。 I want to select/change color of cells manually. 我想手动选择/更改单元格的颜色。

How can I fix this? 我怎样才能解决这个问题?

不要忘记UICollectionView具有嵌入式重用机制,因此您应该直接在单元格类内部的“ prepareToReuse”方法中取消选择单元格。

Take a class-level variable, say index 取一个类级变量,比如说index

var index = -1

As you have said that multiple selections are not allowed so the following will do the job for you 如您所说,不允许多项选择,因此以下内容将为您完成工作

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

Whenever user tap on any cell we save the position in index variable and then call the reloadData() to notify collectionView about the change In cellForRowAt we check if the current cell us selected we set the color to red otherwise white 每当用户点击任意一个单元格时,我们会将位置保存在index变量中,然后调用reloadData()通知collectionView有关更改的信息。在cellForRowAt我们检查是否选择了当前单元格,将颜色设置为红色,否则设置为白色

First, if you want to preserve multiple selection , you have to remember your selected ones in an array since it would get lost if a cell gets recycled and reused. 首先,如果要保留多个选择 ,则必须记住数组中的所选内容,因为如果回收和重复使用单元,它将丢失。 For that use something like a [IndexPath] type). 为此,请使用[IndexPath]类型)。 If one selected cell is enough, you could use a non-array version of below code. 如果一个选定的单元格已足够,则可以使用以下代码的非数组版本。

var selectedItems: [IndexPath] = []

Then, do your recoloring in your cell's cellForItemAt(:) : 然后,在单元格的cellForItemAt(:)

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

Your didSelectItemAt delegate function should look like: 您的didSelectItemAt委托函数应类似于:

if !selectedItems.contains(indexPath) { selectedItems.append(indexPath)}

collectionView.cellForItem(at: indexPath)?.backgroundColor = .red

and your didDeselectItemAt delegate function: 和您的didDeselectItemAt委托函数:

if let index = selectedItems.firstIndex(of: indexPath) { selectedItems.remove(at: index) }

collectionView.cellForItem(at: indexPath)?.backgroundColor = .white

This should actually work. 这实际上应该工作。 Let me know if we have to do adjustments. 让我知道是否需要进行调整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM