商城篩選的功能的Demo,實現(xiàn)如下功能:【CollectionView】初步展示數(shù)據(jù),Section展開/折疊,以及用戶選擇。
先展示幾張Demo界面圖

Demo初始界面值

點擊選擇
分析實現(xiàn)步驟
1.數(shù)據(jù)
手動創(chuàng)建一個FiltrateItem.plist,如下圖展示數(shù)據(jù)模型結構

plist
2.懶加載初始化CollectionView,字典轉模型,設置數(shù)據(jù)源
- (UICollectionView *)collectionView
{
if (!_collectionView) {
UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new];
layout.minimumLineSpacing = 10; //豎間距
layout.itemSize = CGSizeMake((FiltrateViewScreenW - 6 * 5) / 3, 30);
_collectionView = [[UICollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:layout];
_collectionView.delegate = self;
_collectionView.dataSource = self;
_collectionView.alwaysBounceVertical = YES;
_collectionView.frame = CGRectMake(5, 0, FiltrateViewScreenW - DCMargin, ScreenH - 50);
_collectionView.showsVerticalScrollIndicator = NO;
[_collectionView registerClass:[DCAttributeItemCell class] forCellWithReuseIdentifier:DCAttributeItemCellID];//cell
[_collectionView registerNib:[UINib nibWithNibName:NSStringFromClass([DCHeaderReusableView class]) bundle:nil] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:DCHeaderReusableViewID]; //頭部
[_collectionView registerClass:[DCFooterReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:DCFooterReusableViewID]; //尾部
}
return _collectionView;
}
#pragma mark - 篩選Item數(shù)據(jù)
- (void)setUpFiltrateData
{
_filtrateItem = [DCFiltrateItem mj_objectArrayWithFilename:@"FiltrateItem.plist"];
}
#pragma mark - <UICollectionViewDelegate>
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
//這里默認第一組品牌展示兩行數(shù)據(jù)其余展示一行數(shù)據(jù)(3個一行)
return (_filtrateItem[section].isOpen == YES) ? self.filtrateItem[section].content.count : (section == 0) ? 6 : 3 ;
}
Demo中篩選控制的寬度我定義宏為窗口的寬度*0.8 ,每個Item的寬度為(FiltrateViewScreenW - 6 * 5) / 3,已經(jīng)手動算上間距 如下圖

間距圖
#define FiltrateViewScreenW ScreenW * 0.8 //篩選寬宏
layout.itemSize = CGSizeMake((FiltrateViewScreenW - 6 * 5) / 3, 30); //算橫間距
layout.minimumLineSpacing = 10; //豎間距
判斷是否展開或關閉,判斷Item是否點擊,模型中加入兩個BooL值
/** 用于判斷當前cell是否展開 */
@property (nonatomic, assign) BOOL isOpen;
/** 是否點擊 */
@property (nonatomic,assign)BOOL isSelect;
在DCAttributeItemCell中創(chuàng)建一個按鈕,按鈕contentButton尺寸為DCAttributeItemCell的尺寸,根據(jù)模型數(shù)據(jù)的isSelect數(shù)據(jù),改變字體,背景顏色等設置,注意一定記得要把按鈕的enabled設置為NO,不然點擊事件就在按鈕上不在DCAttributeItemCell上,didSelectItemAtIndexPath方法也就失效了
#pragma mark - Setter Getter Methods
- (void)setContentItem:(DCContentItem *)contentItem
{
_contentItem = contentItem;
[_contentButton setTitle:contentItem.content forState:0];
if (contentItem.isSelect) { //已選
[_contentButton setImage:[UIImage imageNamed:@"isSelectYes"] forState:0];//鉤圖片
[_contentButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
_contentButton.backgroundColor = [UIColor whiteColor];
[DCSpeedy dc_chageControlCircularWith:self AndSetCornerRadius:3 SetBorderWidth:1 SetBorderColor:[UIColor redColor] canMasksToBounds:YES];
}else{
[_contentButton setImage:nil forState:0];
[_contentButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
_contentButton.backgroundColor = [UIColor colorWithRed:230/255.0 green:230/255.0 blue:230/255.0 alpha:1.0];
[DCSpeedy dc_chageControlCircularWith:self AndSetCornerRadius:3 SetBorderWidth:1 SetBorderColor:[UIColor clearColor] canMasksToBounds:YES];
}
}
3.根據(jù)模型獲取每組選擇的數(shù)據(jù)和最后總獲得數(shù)據(jù)
點擊事件,通過模型講已選的屬性加入數(shù)組中,這個主意我初始化的數(shù)組內部還嵌套了多個數(shù)組層次結構類似:@[@[],@[],@[]],這樣我們根據(jù)內部數(shù)組的值來給每個Header賦值
#pragma mark - <UICollectionViewDelegate>
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
_filtrateItem[indexPath.section].content[indexPath.row].isSelect = !_filtrateItem[indexPath.section].content[indexPath.row].isSelect;
//數(shù)組mutableCopy初始化,for循環(huán)加數(shù)組 結構大致:@[@[],@[]] 如此
_seleArray = [@[] mutableCopy];
for (NSInteger i = 0; i < _filtrateItem.count; i++) {
NSMutableArray *section = [@[] mutableCopy];
[_seleArray addObject:section];
}
//把所選的每組Item分別加入每組的數(shù)組中
for (NSInteger i = 0; i < _filtrateItem.count; i++) {
for (NSInteger j = 0; j < _filtrateItem[i].content.count; j++) {
if (_filtrateItem[i].content[j].isSelect == YES) {
[_seleArray[i] addObject:_filtrateItem[i].content[j].content];
}else{
[_seleArray[i] removeObject:_filtrateItem[i].content[j].content];
}
}
}
[collectionView reloadData];
}
header頭部折疊展開點擊Block回調和賦值已選屬性
__weak typeof(self)weakSelf = self;
headerView.sectionClick = ^{
weakSelf.filtrateItem[indexPath.section].isOpen = !weakSelf.filtrateItem[indexPath.section].isOpen; //打開取反
[collectionView reloadData]; //刷新
};
//給每組的header的已選label賦值~
NSArray *array = _seleArray[indexPath.section];
NSString *selectName = @"";
for (NSInteger i = 0; i < array.count; i ++ ) {
if (i == array.count - 1) {
selectName = [selectName stringByAppendingString:[NSString stringWithFormat:@"%@",array[i]]];
}else{
selectName = [selectName stringByAppendingString:[NSString stringWithFormat:@"%@,",array[i]]];
}
}
headerView.selectHeadLabel.text = (selectName.length == 0) ? @"全部" : selectName;
headerView.selectHeadLabel.textColor = ([headerView.selectHeadLabel.text isEqualToString:@"全部"]) ? [UIColor darkGrayColor] : [UIColor redColor];
4.底部重置,確定點擊事件處理
#pragma mark - 點擊事件
- (void)bottomButtonClick:(UIButton *)button
{
if (button.tag == 0) {//重置點擊
for (NSInteger i = 0; i < _filtrateItem.count; i++) {
for (NSInteger j = 0; j < _filtrateItem[i].content.count; j++) {
_filtrateItem[i].content[j].isSelect = NO;
[_seleArray[i] removeAllObjects];
}
}
[self.collectionView reloadData];
}else if (button.tag == 1){//確定點擊
for (NSInteger i = 0; i < _seleArray.count; i++) {
NSArray *array = _seleArray[i];
NSString *selectName = @"";
for (NSInteger i = 0; i < array.count; i ++ ) {
if (i == array.count - 1) {
selectName = [selectName stringByAppendingString:[NSString stringWithFormat:@"%@",array[i]]];
}else{
selectName = [selectName stringByAppendingString:[NSString stringWithFormat:@"%@,",array[i]]];
}
}
if (selectName.length != 0) {
NSLog(@"已選:第%zd組 的 %@",i,selectName);
}
}
}
}
這樣我們商品的篩選就簡單的實現(xiàn)了,下面附上一個演示GIF

演示GIF