11

I have UICollection in which there will be number of Students items and each item having switch inside it used for recording attendance. I am loop through all visible cells like this.

for(attendancecollectionViewCell* cells in [[self collectionView] visibleCells]){

    NSLog(@"The switch value : %c",cells.attendanceSwitchLabel.isOn);

}

But, I wanted to loop through all the cells for attendance, not just the visible cells.

Ayan
  • 515
  • 4
  • 9
  • 20

2 Answers2

17

You cannot loop through non-visible cells because those cells don't exist. UICollectionView, like UITableView, reuses cells as soon as they are offscreen. I.e., if you scroll down, it takes a cell that has been scrolled off and uses it for a "new" cell about to be scrolled into view.

If you wish to hold state for an entry in your collection, you'll have to store it separately from the cell itself. For example, an NSArray of structs (or custom NSObjects) that map to the indexPath.row value.

A more important question for you specifically would be: What are you trying to achieve in your for loop?

Let me know if you need more information or sample code.

Zak Arntson
  • 372
  • 2
  • 8
  • I think I valid example of wanting to access the non-visible cells - my question on this is here if you had a sec http://stackoverflow.com/questions/33259244/how-to-redraw-non-visible-uicollectionviewcells-after-rotation-ready-for-when-r – Greg Oct 23 '15 at 10:40
  • 8
    "because those cells don't exist": this is not true. The cells do exist as they are reused. They exist and are waiting to be reused. But i have reproductable proof where cells are NOT in visibleCells and are used again (ie: without a call to DequeueReusableCell). – Softlion Dec 19 '16 at 07:17
  • 6
    @Softlion I had the same problem. Turns out it's an iOS10 thing, where cells stay around sometimes even after going off-screen. You can disable this behavior by doing ```collectionView.prefetchingEnabled = NO``` – alemangui Jan 18 '17 at 10:38
  • @Softlion I added my notification sample to other question which is more specific to your use case http://stackoverflow.com/questions/33259244/how-to-redraw-non-visible-uicollectionviewcells-after-rotation-ready-for-when-r – johndpope Mar 24 '17 at 16:37
  • If you don't want to turn off prefetching you can iterate through collectionView.subviews handling the views that can cast to a cell. This will get visible and off-screen cells. This is not an idea solution since it assumes UICollectionView will always add cells directly to itself, rather than to a subview, but works as of iOS 12. – Devin Pitcher Feb 15 '19 at 18:30
0

Swift 4+

func getAllCells() -> [UICollectionViewCell] {
    
    var cells = [UICollectionViewCell]()
    // assuming tableView is your self.tableView defined somewhere
    
    for i in 0...self.numberOfSections-1
    {
        for j in 0...self.numberOfItems(inSection: i) - 1
        {
            if let cell = self.cellForItem(at: NSIndexPath(row: j, section: i) as IndexPath) {
                
                cells.append(cell)
            }
            
        }
    }
    return cells
}
Community
  • 1
  • 1
Zumry Mohamed
  • 9,318
  • 5
  • 46
  • 51