Selecting All The Items in UIcollectionview iOS, Even The Cells That Are Not Visible

Selecting all the items in UICollectionView iOS, even the cells that are not visible

It is not possible to have all cells selected when using cell reuse.

Due to cell reuse the number of actual cells which exist at any moment is a couple more than the number of cells currently visible.
i.e. 6 cells visible is about 8 cells existing.

You are able to find out how many visible cells there are with

NSArray *visiblePaths = [self.collectionView indexPathsForVisibleItems];

The solution is to have the selected value stored within the UICollectionView datasource and use that value for when you customise a cell inside cellForItemAtIndexPath

How to select all UICollectionView Cell's and Deselect by button click?

I'm not sure why sometimes you use "indexPath.row" and sometimes "indexPath.item".

Regardless, your function should look something like this

@IBAction func selectAllA(_ sender: Any) {
arraySelectedFilterIndex.removeAll()
arraySelectedFilterData.removeAll()

for (index, element) in self.filterTitles.enumerated() {
arraySelectedFilterIndex.append(IndexPath(item: index, section: 0))
arraySelectedFilterData.append(element)
}

collectionView.reloadData()
print(arraySelectedFilterData)
}

At first you are clearing previous selections to avoid duplicates, you could use a map/dictionary structure to avoid duplicated instead of a list though.

Then for each element you add the index and data to the selected list. Finally reload the data, I kept you the print at the end so you can check it.

Select not visible cell inside a collection

Well after a lot of searching, what works for me is to set a local variable say: selectedCell , then when I want to show a previous user selected cell, i will just set the variable , and on :

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
if(indexPath.row==selectedCell)
}

I am checking if its already selected and mark it .
I could not find any other clever way of doing so automatically .

UICollectionView - Select all cells doesn't update properly

Your code is a little confused because you are trying to keep track of cell selection state both in an array and in the cell itself.

I would just use a Set<IndexPath> as it is simpler and more efficient than an array. You can then refer to this set when returning a cell in cellForItemAt: and you don't need to do anything in willDisplay.

When you select/deselect all you can just reload the whole collection view and when an individual cell is selected/deselected, just reload that cell.

@objcMembers
class MainViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

@IBOutlet var collectionView: UICollectionView!
@IBOutlet var toolBar: UIToolbar?
@IBOutlet weak var selectButton: UIBarButtonItem!

var selectedCells = Set<IndexPath>()
var isSelectAllActive = false

// MARK: - Classes
override func viewDidLoad() {
super.viewDidLoad()

// Collection view
collectionView!.delegate = self
collectionView!.dataSource = self
collectionView!.allowsMultipleSelection = true
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}

override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}

@IBAction func selectButtonTapped(_ sender: Any) {
if isSelectAllActive {
// Deselect all cells
selectedCells.removeAll()

selectButton.title = "Select all"
isSelectAllActive = false
} else {
// Select all cells
for i in 0 ..< collectionView!.numberOfItems(inSection: 0) {
self.selectedCells.insert(IndexPath(item:i, section:0))
}

selectButton.title = "Select none"
isSelectAllActive = true
}
self.collectionView.reloadData()
}

func numberOfSections(in collectionView: UICollectionView) -> Int {
return 1
}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 50
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell: UICollectionViewCell
cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CVCell", for: indexPath)
if self.selectedCells.contains(indexPath) {
cell.backgroundColor = .green
} else {
cell.backgroundColor = .white
}
if cell.viewWithTag(1) != nil {
let cellTitle = cell.viewWithTag(1) as! UILabel
cellTitle.text = String(indexPath.row)
}
return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("\ndidSelectItemAt: \(indexPath.row)")
if selectedCells.contains(indexPath) {
selectedCells.remove(indexPath)
} else {
selectedCells.insert(indexPath)
}
self.collectionView.deselectItem(at: indexPath, animated: false)
self.collectionView.reloadItems(at: [indexPath])

print("selectedCells: \(selectedCells)")
}
}

UICollectionView - Not displaying cells

Since I didn't find a direct solution to it I've tried to set up a new project and did the same changes and tweaks and surprisingly, this time, everything worked from the beginning. I then copied the storyboard to my old project, deleted all the old files and replaced it with the files from the new project. Everything is working good so far. I have no idea what the actual error was but I'm happy it's working now. Thanks to everyone who had a look at my question!

UICollectionView how to deselect all

Not all of the selected cells may be on screen at the point when you are clearing the selection status, so collectionView.cellForItemAtIndexPath(indexPath) may return nil. Since you have a force downcast you will get an exception in this case.

You need to modify your code to handle the potential nil condition but you can also make your code more efficient by using the indexPathsForSelectedItems property of UICollectionView

 let selectedItems = followCollectionView.indexPathsForSelectedItems
for (indexPath in selectedItems) {
followCollectionView.deselectItemAtIndexPath(indexPath, animated:true)
if let cell = followCollectionView.cellForItemAtIndexPath(indexPath) as? FollowCell {
cell.checkImg.hidden = true
}
}

UICollectionView is selecting multiple cell even multiple cell selection is false

You should make use of the "isSelected" method for the collection view cell. The way you are doing it is only selecting the cell there is no way of unselecting it. Also, you will need to unselect the previous selected cell If there are any.

So I recommend using this method:

Firstly,

        collectionView.allowsMultipleSelection = false

on the UICollectionViewCell you can override the isSelected method

didSet {
if isSelected {
// Change UI for selected state
radioButton.setImage(#imageLiteral(resourceName: "greenTick"), for: .normal)
} else {
// Chage UI for unselected state
radioButton.setImage(#imageLiteral(resourceName: "radioInactive"), for: .normal)
}
}

Finally when you need to find out the indexpath for the selected item.

            guard let selectedIndex = self.collectionView.indexPathsForSelectedItems?.first else { return }


Related Topics



Leave a reply



Submit