如果从 UICollectionView 的其他部分中选择了一个单元格,则取消选择所有其他选择
Posted
技术标签:
【中文标题】如果从 UICollectionView 的其他部分中选择了一个单元格,则取消选择所有其他选择【英文标题】:Deselect all other selections if one cell selected from other section in UICollectionView 【发布时间】:2016-12-29 13:02:28 【问题描述】:如果从第 1 节中选择了任何单元格,如何取消选择第 0 节中 UICollectionView 中的所有其他选定单元格。 以下是我到目前为止尝试过的:
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)
let cell = collectionView.cellForItemAtIndexPath(indexPath) as! SignupStep3CollectionViewCell
cell.layer.borderWidth = 4
cell.layer.masksToBounds = false
cell.layer.borderColor = UIColor.init(red: 46.0/255.0, green: 234.0/255.0, blue: 219.0/255.0, alpha: 1.0).CGColor
cell.layer.cornerRadius = cell.frame.height/2
cell.clipsToBounds = true
if indexPath.section == 1
collectionView.selectItemAtIndexPath(nil, animated: true, scrollPosition: .None)
这不起作用,请指导。
【问题讨论】:
【参考方案1】:试试这个。
斯威夫特 3
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool
//multiple selection in section 0 otherwise single selection in other section
if indexPath.section == 0
return true
let indexPaths = collectionView.indexPathsForSelectedItems
if (indexPaths?.count) ?? 0 > 0
/// If you need simple way
for index in indexPaths!
if index.section == indexPath.section
self.collectionView.deselectItem(at: index, animated: true) // if want deselect previous selection
//return false //if you do not want further selection
/// If you need some optimization and don't want to run loop each time
/*
let arrIndexPaths = NSArray(array: indexPaths!)
let sectionPrediate = NSPredicate(format: "section == %d", indexPath.section)
let arrSelections = arrIndexPaths.filtered(using: sectionPrediate) as? [IndexPath]
if arrSelections?.count ?? 0 > 0
self.collectionView.deselectItem(at: arrSelections![0], animated: true) // if want deselect previous selection
//return false //if you do not want further selection
*/
return true
斯威夫特 2.3
func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool
//multiple selection in section 0 otherwise single selection in other section
if indexPath.section == 0
return true
let indexPaths = collectionView.indexPathsForSelectedItems()
if (indexPaths?.count) ?? 0 > 0
/// If you need simple way
for index in indexPaths!
if index.section == indexPath.section
self.colletionView.deselectItemAtIndexPath(index, animated: true) // if want deselect previous selection
//return false //if you do not want further selection
/// If you need some optimization and don't want to run loop each time
/*let arrIndexPaths = NSArray(array: indexPaths!)
let sectionPrediate = NSPredicate(format: "section == %d", indexPath.section)
let arrSelections = arrIndexPaths.filteredArrayUsingPredicate(sectionPrediate) as? [NSIndexPath]
if arrSelections?.count ?? 0 > 0
self.colletionView.deselectItemAtIndexPath(arrSelections![0], animated: true) // if want deselect previous selection
//return false //if you do not want further selection
*/
return true
【讨论】:
“NSIndexpath 不符合协议序列类型”错误来了 你在使用 Swift3 吗?因为这适用于 Xcode 8.1 好的,然后尝试在 swift 2 中转换我的代码。我认为它会对您有所帮助... 能否请您写在 swift 2 中不知道 swift 3? 这个逻辑我现在已经实现了,并且在选择第 1 项时还设法清除所有选择。现在面临的问题是滚动选择错误。似乎是双端队列可重用性的问题。请指导一下?【参考方案2】:您可以实现以下委托方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)
let section = indexPath.section
let selectedRows = collectionView.indexPathsForSelectedItems
for i in 0...(selectedRows!.count - 1)
let path = selectedRows![i] as IndexPath
if(path.section != section)
collectionView.deselectItem(at: path, animated: false)
在选择任何特定项目时,您可以获得所有选定的项目。然后取消选择来自不同部分的所有项目。
【讨论】:
“NSIndexpath 不符合协议序列类型”错误来了 更新了答案。你现在可以检查吗? 能否请您写在 swift 2 中不知道 swift 3?【参考方案3】:基于 Mrugesh 的回答,但也考虑到第 1 节要求中的单一选择:
斯威夫特 2:
func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool
let indexPaths = collectionView.indexPathsForSelectedItems()
if indexPaths?.count ?? 0 > 0
if indexPaths![0].section != indexPath.section || indexPath.section == 1
for index in indexPaths!
collectionView.deselectItemAtIndexPath(index, animated: true)
return true
斯威夫特 3:
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool
let indexPaths = collectionView.indexPathsForSelectedItems
if (indexPaths?.count) ?? 0 > 0
if indexPaths![0].section != indexPath.section || indexPath.section == 1
for index in indexPaths!
collectionView.deselectItem(at: index, animated: true)
return true
根据你的视图控制器是UICollectionViewController
的子类还是仅仅实现了它的委托和数据源协议,你可能需要override
这个函数。
【讨论】:
它只允许我启用第 0 节多选和第 1 节单选。但如果选择了第 1 节中的任何单元格,则不会清除第 0 节的选择。 这很奇怪。它适用于一个带有集合视图的简单应用程序,使用cell.selected
来确定单元格应具有的背景颜色。 indexPathsForSelectedItems
也会打印正确的选择。我不能同时选择第 0 节和第 1 节。您如何确定选择的内容?【参考方案4】:
使用下面的代码来解决问题:- 清除第 1 节的点击单元格上的第 0 节选择。 // didSelect 方法
let indexSet = NSIndexSet(index: 1)
self.collectionViewBrands.reloadSections(indexSet)
【讨论】:
以上是关于如果从 UICollectionView 的其他部分中选择了一个单元格,则取消选择所有其他选择的主要内容,如果未能解决你的问题,请参考以下文章
如果从 UICollectionView 的其他部分中选择了一个单元格,则取消选择所有其他选择