繁体   English   中英

选择UICollectionView iOS中的所有项目,甚至是不可见的单元格

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

我正在创建一个应用程序,我在工具栏上有一个按钮,用于选择集合视图中的所有项目。

但我面临的问题是,当我点击按钮时,它只选择屏幕上可见的项目。 这是由于CELL REUSE功能。

有没有什么方法可以选择所有单元格,甚至那些当前对用户不可见的单元格?

谢谢J

即使使用单元重用,这也是可能的。 您可以在第一部分中选择所有单元格:

for (NSInteger row = 0; row < [self.collectionView numberOfItemsInSection:0]; row++) {
    [self.collectionView selectItemAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:NO scrollPosition:UICollectionViewScrollPositionNone];
}

如果你有超过1个部分,只需使用另一个嵌套的for循环来遍历所有部分。

使用单元重用时,不可能选择所有单元。

由于细胞重用,在任何时刻存在的实际细胞的数量比当前可见的细胞数量多几倍。 即,可见的6个细胞存在约8个细胞。

您可以找出有多少可见细胞

NSArray *visiblePaths = [self.collectionView indexPathsForVisibleItems];

解决方案是将selected值存储在UICollectionView数据源中,并在自定义cellForItemAtIndexPath的单元格时使用该值

我在想要显示照片并允许用户选择多张照片时使用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
    }
}

针对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)
}

Swift 3解决方案:

stride(from: 0, to: collectionView.numberOfItems(inSection: yourSectionIndex), by: 1)
        .forEach{ collectionView.selectItem(at: IndexPath(row: $0, section: yourSectionIndex), animated: true, scrollPosition: []) }

我在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)
        })
    }

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM