CollectionView多選

寫在前面

collectionView的多選是個老生常談的問題了,但是當首次實現的時候還是要注意點什麼的。

實現多選

這倆屬性控制這些items是否可以選擇,如果是,是否可以同時選擇多個。

// These properties control whether items can be selected, and if so, whether multiple items can be simultaneously selected.
@property (nonatomic) BOOL allowsSelection; // default is YES
@property (nonatomic) BOOL allowsMultipleSelection; // default is NO

只需要 allowsMultipleSelection = YES你的collectionView就支持多選了。
你可能會問,我怎麼沒看到,看這裏
collectionView有一個屬性,保存着被選中item的indexPath

@property (nonatomic, readonly, nullable) NSArray<NSIndexPath *> *indexPathsForSelectedItems; // returns nil or an array of selected index paths

在這兩個方法裏面打印一下,就會看到,點擊選中,點擊取消選中,記錄的一點都沒錯。-collectionView: didSelectItemAtIndexPath:
collectionView: didDeselectItemAtIndexPath:
那麼怎麼讓他顯示出來呢,接着去看UICollectionViewCell的API,通過重寫這兩個方法,你不僅可以自定義selected的UI,還可以自定義highlighted的

// Cells become highlighted when the user touches them.
// The selected state is toggled when the user lifts up from a highlighted cell.
// Override these methods to provide custom UI for a selected or highlighted state.
// The collection view may call the setters inside an animation block.
@property (nonatomic, getter=isSelected) BOOL selected;
@property (nonatomic, getter=isHighlighted) BOOL highlighted;

要記得先調用父類的

- (void)setSelected:(BOOL)selected {
    [super setSelected:selected];
    self.backgroundColor = selected ? [UIColor yellowColor] : [UIColor cyanColor];
}

到此結束,你只需要做這麼多。

全選,取消全選

這裏用到了四個方法

  • - (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath;
  • - (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath; // called when the user taps on an already-selected item in multi-select mode

  • - (void)selectItemAtIndexPath:(nullable NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition;

  • - (void)deselectItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated;

前兩個根據自己的需要返回YES或NO,後面兩個文檔上有句話需要注意:
This method does not cause any selection-related delegate methods to be called.
意思說着兩個方法不會導致任何選中,取消選中的代理方法被調用。刷新UI需要手動處理。

- (void)selectedAllorCancel:(UIBarButtonItem *)item {
    if ([item.title isEqualToString:@"全選"]) {
        [item setValue:@"取消" forKey:@"title"];
        [self shouldSelectedAll:YES];
    }else {
        [item setValue:@"全選" forKey:@"title"];
        [self shouldSelectedAll:NO];
    }
}

- (void)shouldSelectedAll:(BOOL )selectedAll {

    for (NSIndexPath *indexPath in self.collectionView.indexPathsForVisibleItems) {
        if (selectedAll) {
            if ([self collectionView:self.collectionView shouldSelectItemAtIndexPath:indexPath]) {

                [self.collectionView selectItemAtIndexPath:indexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone];
                LCRegionCell *cell = (LCRegionCell*)[self.collectionView cellForItemAtIndexPath:indexPath];
                cell.selected = YES;

            }
        }else {
            if ([self collectionView:self.collectionView shouldDeselectItemAtIndexPath:indexPath]) {

                [self.collectionView deselectItemAtIndexPath:indexPath animated:YES];
                LCRegionCell *cell = (LCRegionCell*)[self.collectionView cellForItemAtIndexPath:indexPath];
                cell.selected = NO;
            }
        }

    }
}

之前看說要用到這個方法,實際操作不用也沒什麼區別,感覺這裏並不需要,還望告知解惑。

- (void)performBatchUpdates:(void (NS_NOESCAPE ^ _Nullable)(void))updates completion:(void (^ _Nullable)(BOOL finished))completion; // allows multiple insert/delete/reload/move calls to be animated simultaneously. Nestable.

注意:爲節省時間這裏整個collectionView的所有item遍歷的是collectionView.indexPathsForVisibleItems,也就是說僅在當前屏幕上顯示的item,項目根據需求去遍歷

總結

總的來說collectionView很強大,可以這麼說,凡是用tableView實現的用collectionView同樣可以,支持的功能要比tableView要多。還有很多待發現的功能,api文檔是最好的學習途徑。

這裏寫圖片描述

發佈了87 篇原創文章 · 獲贊 17 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章