【问题标题】:Selecting all the items in UICollectionView iOS, even the cells that are not visible选择 UICollectionView iOS 中的所有项目,甚至是不可见的单元格
【发布时间】:2013-11-11 22:06:14
【问题描述】:

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

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

有什么方法可以选择所有单元格,即使是当前对用户不可见的单元格?

谢谢 J

【问题讨论】:

  • 这个可以,你用的是什么代码?

标签: ios objective-c uicollectionview


【解决方案1】:

即使重复使用单元格,这也是可能的。您可以通过以下方式选择第一部分中的所有单元格:

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

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

【讨论】:

    【解决方案2】:

    我遇到了同样的问题,我想显示照片并允许用户选择多张照片,包括全选和全选选项。 原来 [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】:

      为 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 没有selectItem(atIndexPath: ... 而是select(at indexPath: ...
      【解决方案4】:

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

      由于单元重用,在任何时候存在的实际单元的数量比当前可见的单元的数量多几个。 即可见的 6 个单元格大约存在 8 个单元格。

      您可以找出有多少可见单元格

      NSArray *visiblePaths = [self.collectionView indexPathsForVisibleItems];
      

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

      【讨论】:

      • 事实上,即使使用单元重用,也可以选择所有单元 - 请参阅下面的答案。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        Swift 3 解决方案:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多