我正在尝试实现此功能:在我的应用中,如果我在UICollectionView中选择了一个单元格,则边框变为蓝色,如果我选择另一个,则应取消选择前一个并且边框应变为透明。我写过一些方法:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ChatCell
/* Set some settings */
if globalSelected[indexPath.item] {
cell.circleView.layer.borderColor = UIColor.blue.cgColor
} else {
cell.circleView.layer.borderColor = UIColor.clear.cgColor
}
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//Global variable for maintain selection
global.selectedChatPath = indexPath
globalSelected[indexPath.item] = true
collectionView.reloadData()
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
if indexPath != nilPath {
globalSelected[indexPath.item] = false
collectionView.reloadData()
}
}
nilPath 只是 IndexPath(item:-1,section:0) ,但它没有没关系,因为甚至没有调用 collectionView(_ collectionView:UICollectionView,didDeselectItemAt indexPath:IndexPath) 。我的CollectionView具有 allowSelection = true 和 allowsMultipleSelection = false 属性。我会感谢任何帮助。
答案 0 :(得分:3)
如果同时只选择一个单元格我建议将当前选择的索引路径放入实例变量(nil
表示没有选择任何内容)
var selectedIndexPath : IndexPath?
在cellForItemAt
中根据实例变量设置颜色
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ChatCell
/* Set some settings */
if let selected = selectedIndexPath, selected == indexPath {
cell.circleView.layer.borderColor = UIColor.blue.cgColor
} else {
cell.circleView.layer.borderColor = UIColor.clear.cgColor
}
return cell
}
在didSelectItemAt
中仅重新加载上一个和新选择的单元格,并将selectedIndexPath
设置为新选择的索引路径。这比重新加载整个集合视图更有效。
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
//Global variable for maintain selection
var cellsToReload = [indexPath]
if let selected = selectedIndexPath {
cellsToReload.append(selected)
}
selectedIndexPath = indexPath
collectionView.reloadItems(at: cellsToReload)
}
仅当您要明确取消选择单元格时才需要 didDeselectItemAt
。
答案 1 :(得分:1)
试试这个
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ChatCell
/* Set some settings */
if globalSelected[indexPath.item] {
cell.circleView.layer.borderColor = UIColor.blue.cgColor
collectionView.selectItemAtIndexPath(indexPath, animated: false, scrollPosition: .None)
}
else {
cell.circleView.layer.borderColor = UIColor.clear.cgColor
collectionView.deselectItemAtIndexPath(indexPath, animated: false)
}
return cell
}
答案 2 :(得分:0)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! CollectionViewCell
if selectedIndex == indexPath.item {
cell.backgroundColor = .blue
} else {
cell.backgroundColor = .clear
}
}
和didSelectItemAt,
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
selectedIndex = indexPath.item
collectionView.reloadData()
}
答案 3 :(得分:0)
每次选择单元格时重新加载UICollectionView,然后更改所需单元格的边框。 当您重新加载数据时,前一个单元格的边框将被删除,之后您可以将边框添加到所需的单元格。
答案 4 :(得分:0)
didDeselectItem
在您再次点击所选单元格之前不会被调用。要在点击其他单元格时取消选择先前选定的单元格,您需要将全局变量中先前选定的单元格设置设置为false
中的didSelectItem
,如下所示:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
globalSelected[global.selectedChatPath.item] = false //Set the previously selected cell's setting to false
//Global variable for maintain selection
global.selectedChatPath = indexPath
globalSelected[indexPath.item] = true
collectionView.reloadData()
}