Is there a way to determine the order of the self.collectionview.visiblecells?
Updated for Swift5
let visibleCells = self.collectionView.indexPathsForVisibleItems
.sorted { left, right -> Bool in
return left.section < right.section || left.row < right.row
}
.compactMap { [weak self] in indexPath -> UICollectionViewCell? in
return self?.collectionView.cellForItem(at: indexPath)
}
Please note that any self
in closure would keep a strong reference if not weaken.
let visibleCells = self.collectionView.indexPathsForVisibleItems
.sorted { $0.section < $1.section || $0.row < $1.row }
.flatMap { [weak self] in self?.collectionView.cellForItem(at: $0) }
Swift3
Based on previous answer, here is a Swift3 equivalent to get ordered visible cells, first ordering visible indexpath, then fetching UICollectionViewCell using sorted
and flatMap
.
let visibleCells = self.collectionView.indexPathsForVisibleItems
.sorted { left, right -> Bool in
return left.section < right.section || left.row < right.row
}.flatMap { [weak self] in indexPath -> UICollectionViewCell? in
return self?.collectionView.cellForItem(at: indexPath)
}
In an even more simplified version, a bit less readable
let visibleCells = self.collectionView.indexPathsForVisibleItems
.sorted { $0.section < $1.section || $0.row < $1.row }
.flatMap { [weak self] in self?.collectionView.cellForItem(at: $0) }
Returning the first item visible on the collectionView:
UICollectionViewCell *cell = [self.collectionView.visibleCells firstObject];
returning the first item from all the items in the collectionView
UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:0]];
You don't want the cell, just the data:
NSIndexPath *indexPath = [[self.collectionView indexPathsForVisibleItems] firstObject];
id yourData = self.dataSource[indexPath.row];
But the visivleCells array is not ordered!!
Well, then you need to order it:
NSArray *indexPaths = [self.collectionView indexPathsForVisibleItems];
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"row" ascending:YES];
NSArray *orderedIndexPaths = [indexPaths sortedArrayUsingDescriptors:@[sort]];
// orderedIndexPaths[0] would return the position of the first cell.
// you can get a cell with it or the data from your dataSource by accessing .row
Edit: i do believe the visibleCells (and the like) return ordered already, but i didn't find anything regarding this on the docs. so i added the ordering part just to make sure.