我正在创建一个应用程序,我在工具栏上有一个按钮,用于选择集合视图中的所有项目。
但我遇到的问题是,当我点击按钮时,它只选择屏幕上可见的项目。这是由于CELL REUSE功能。
有什么方法可以选择所有单元格,甚至是用户当前看不到的单元格?
由于 Ĵ
答案 0 :(得分:16)
即使细胞重复使用也是如此。您可以通过以下方式选择第一部分中的所有单元格:
for (NSInteger row = 0; row < [self.collectionView numberOfItemsInSection:0]; row++) {
[self.collectionView selectItemAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:NO scrollPosition:UICollectionViewScrollPositionNone];
}
如果你有超过1个部分,只需使用另一个嵌套for循环遍历所有部分。
答案 1 :(得分:4)
使用单元格重用时,无法选择所有单元格。
由于细胞重复使用,任何时刻存在的实际细胞数量比当前可见的细胞数量多一些。 即可见的6个细胞约有8个细胞存在。
您可以通过
找出有多少可见细胞NSArray *visiblePaths = [self.collectionView indexPathsForVisibleItems];
解决方案是将selected
值存储在UICollectionView数据源中,并在自定义cellForItemAtIndexPath
内的单元格时使用该值
答案 2 :(得分:4)
我在想要显示照片并允许用户选择多张照片时使用select-all和deselct-all选项时遇到了同样的问题。 事实证明,[self.collectionView selectItemAtIndexPath:]不适用于选择所有单元格。
所以我最终在维护一个单独的状态标志和数据源。在我的例子中,每个单元格都显示了一张照片,因此我必须维护一个单独的BOOL数组,其中每个元素代表数据源数组中相应照片的当前选择状态。
请参阅以下代码: (来源:http://heliumapps.weebly.com/blog/uicollectionview-and-cell-selection)
@interface PhotosViewController() {
BOOL *selectedStates; //cell selection states boolean array [C-language array]
/* Let us assume that we have an array for data source, named "myDataSourceArray".
For each element in the array, the correspomding element in selectedStates represents
the selection state of the cell.
*/
}
//load data source
-(void)loadDataSource {
//init the data source array (myDataSourceArray) and populate it with data
//free up the previously allocated memory for selecteStates, if any (in case you reuse this view controller)
if(selectedStates) {
free(selectedStates);
selectedStates = nil;
}
//initilaize the selection states of all cells to NO
selectedStates = malloc(myDataSourceArray.count*sizeof(BOOL));
for(NSUInteger i = 0; i < self.myDataSourceArray.count; i++) {
selectedStates[i] = NO;
}
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath {
PhotoViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:self.reuseIdentifier
forIndexPath:indexPath];
//populate cell with required data & images to display
[cell setPhoto:myDataSourceArray[indexPath.item]];
//configure cell for selection state
[cell configureCellForSelectionState:selectedStates[indexPath.item]];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
[self toggleSelectionOfCellAtIndex:indexPath];
}
- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(nonnull NSIndexPath *)indexPath {
[self toggleSelectionOfCellAtIndex:indexPath];
}
-(void)toggleSelectionOfCellAtIndex:(NSIndexPath*)indexPath{
MyCollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
selectedStates[indexPath.item] = !selectedStates[indexPath.item];
[cell configureForSelectionState];
}
//method to select/deselect all photos
- (void) setStateForAllPhotos:(BOOL)flag {
for(NSUInteger i = 0; i < self.myDataSourceArray.count; i++) {
selectedStates[i] = flag;
}
[self.collectionView reloadData]; //on main thread
}
/* below method in the cell's implementation */
-(void) configureForSelectionState:(BOOL)flag {
if(flag) {
//configure cell for selected state
[cell.layer setBorderColor:[UIColor greenColor].CGColor];
[cell.layer setBorderWidth:2];
} else {
//configure cell for deselected state
}
}
答案 3 :(得分:3)
针对Swift 3进行了更新
更新了Gasper Kolenc对swift 3的回答,以备将来使用,如果有人在swift 3中找到这个,那么...
for row in 0..<self.collectionView!.numberOfItems(inSection: 0) {
self.collectionView!.selectItem(at: IndexPath(row: row, section: 0), animated: false, scrollPosition: .none)
}
答案 4 :(得分:1)
Swift 3解决方案:
stride(from: 0, to: collectionView.numberOfItems(inSection: yourSectionIndex), by: 1)
.forEach{ collectionView.selectItem(at: IndexPath(row: $0, section: yourSectionIndex), animated: true, scrollPosition: []) }
答案 5 :(得分:1)
我已在UICollectionView
上创建了一个简单的扩展程序,用于选择和取消选择:
extension UICollectionView {
/// Iterates through all sections & items and selects them.
func selectAll(animated: Bool) {
(0..<numberOfSections).flatMap { (section) -> [IndexPath]? in
return (0..<numberOfItems(inSection: section)).flatMap({ (item) -> IndexPath? in
return IndexPath(item: item, section: section)
})
}.flatMap { $0 }.forEach { (indexPath) in
selectItem(at: indexPath, animated: true, scrollPosition: [])
}
}
/// Deselects all selected cells.
func deselectAll(animated: Bool) {
indexPathsForSelectedItems?.forEach({ (indexPath) in
deselectItem(at: indexPath, animated: animated)
})
}
}