上图

IOS-筛选设计思想_IOS筛选

数据驱动

几种类型

// 用来区分不用cell的样式等功能,细分到每一个Cell
typedef NS_ENUM(NSInteger, IStarFilterItemType){
    ISTAR_FILTER_TYPE_ROOT,// 根节点,制作挂载用
    ISTAR_FILTER_TYPE_SECTION_TITLE, //section的标题
    ISTAR_FILTER_TYPE_SUB_NORMAL, //如倾向性(全部,正面,负面,中性)
    ISTAR_FILTER_TYPE_ALL, //全部(因为有选中全部的选项,只留下全部的功能)
    //时间的几种类型
    ISTAR_FILTER_TYPE_SUB_TIME, //全部,当天,一周内,等数据 ,都需要两个参数,开始时间和结束时间
    ISTAR_FILTER_TYPE_SUB_CUSTOM_TIME_LONG, //自定义时间,整个的
    ISTAR_FILTER_TYPE_SUB_CUSTOM_TIME_START, //开始时间
    ISTAR_FILTER_TYPE_SUB_CUSTOM_TIME_END, //结束时间
    
    
    ISTAR_FILTER_TYPE_SUB_BREAK_LINE, // 此处单独换一行
    
    //关于自定义筛选的
    ISTAR_FILTER_TYPE_SECTION_TITLE_BIG, //大标题的,例如:自定义筛选
    ISTAR_FILTER_TYPE_LINE_LONG, //整个的一条线,用于Section
};

// 区分选中类型,选择的类型
typedef NS_ENUM(NSInteger, IStarFilterChooseType){
    ISTAR_CHOOSE_SINGLE, //单选
    ISTAR_CHOOSE_MULTI, //多选
    ISTAR_CHOOSE_NO, //只有section需要选择
};

// 用来区分组别,以后就可以添加自定义筛选了, 每一块Section, 理论上说CELL模块是不需要的
typedef NS_ENUM(NSInteger, IStarFilterGroup){
    ISTAR_GROUP_ROOT,
    ISTAR_GROUP_NORMAL, //正常类型
    ISTAR_GROUP_SECTION, // section组
    ISTAR_GROUP_TIME, // 时间的section组
    ISTAR_GROUP_CUTOM, //自定义筛选的section组
    ISTAR_GROUP_1, //动态类型1 —— 主要是动态添加的作用,用于归组
    ISTAR_GROUP_2, //动态类型2 —— 主要是动态添加的作用,用于归组
    ISTAR_GROUP_3, //动态类型3 —— 主要是动态添加的作用,用于归组
};

typedef NS_ENUM(NSInteger, IStarTimeType) {
    ISTAR_TIME_ALL,  //全部
    ISTAR_TIME_TODAY, //当天
    ISTAR_TIME_24,  //24小时
    ISTAR_TIME_3,   //3天
    ISTAR_TIME_7,   //7天
    ISTAR_TIME_CUSTOM //自定义
};


每一个显示的内容都是一个model,

model的种类不同区分是否是标题还是其他。

筛选默认操作

筛选默认操作的时候
// 星光筛选 -
+(IStarFilterModel*)starSortSiftDataWithParam2:(MSIStarSearchSiftModel*)subjectParam{
    // 全部是默认值
//    IStarFilterModel *root = [[IStarFilterModel alloc] initWithDisplayTitle:@"root显示" iStarFilterChooseType:ISTAR_FILTER_TYPE_ROOT iStarFilterGroup:ISTAR_GROUP_ROOT]; //最根目录的
    IStarFilterModel *root = [[IStarFilterModel alloc]
            initWithDisplayTitle:@"root不显示"
            iStarFilterItemType:ISTAR_FILTER_TYPE_ROOT
            iStarFilterChooseType:ISTAR_CHOOSE_NO
            iStarFilterGroup:ISTAR_GROUP_ROOT];
    root.objBool = NO;//是否境外
    // 时间(单选)
    IStarFilterModel * filterTime =[self filterTime];
    NSString* beginTime = [IStarTimeUtils converseTime:subjectParam.beginTime fromFormatter:YYYYMMddHHmmss_ONLY toFormatter:yyyyMMddHHmmSub];
    NSString* endTime = [IStarTimeUtils converseTime:subjectParam.endTime fromFormatter:YYYYMMddHHmmss_ONLY toFormatter:yyyyMMddHHmmSub];
    [MSSxTool selectIStarTimeSection:filterTime select:subjectParam.time btime:beginTime etime:endTime];
    [root addSubArrayModel: filterTime];
    
    // 倾向性(多选)
    IStarFilterModel * filterTendency =[self filterTendency];
    [MSSxTool selectKV_ORIENTATIONSection:filterTendency KV_ORIENTATION:subjectParam.kvOrientation];
    [root addSubArrayModel:filterTendency];
    
    // 微博类型(多选)
    IStarFilterModel * filterWeiboType =[self filterWeiboType];
    [MSSxTool selectWeibotypeSection:filterWeiboType wechatInfoType:subjectParam.wechatInfoType];
    [root addSubArrayModel:filterWeiboType];
    
    // 图片识别(单选)
    IStarFilterModel * filterOcr =[self filterOcr];
    [MSSxTool selectIsOcrSection:filterOcr isOcr:subjectParam.isOcr];
    [root addSubArrayModel:filterOcr];
    
    //自定义帅选
    //[root addSubArrayFromArray:[self filterCustom]];
    //重新选中
    return root;
}

数据的回显

MSSxTool selectKV_ORIENTATIONSection:filterTendency KV_ORIENTATION:subjectParam.kvOrientation];

回复默认值

- (void)resetSiftSource
{
    
    [self.iStarFilterModel.subArray enumerateObjectsUsingBlock:^(IStarFilterModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [obj setDefaultData];
    }];
    [UIView performWithoutAnimation:^{
        [self.homeView reloadData];
    }];
}

IOS-筛选设计思想_单选_02

设计思想

IOS-筛选设计思想_IOS筛选_03

有组织有纪律的管理数据

起止时间

// 起止时间
+(IStarFilterModel*)filterTime{
    IStarFilterModel *sectionTime = [[IStarFilterModel alloc]
                                     initWithDisplayTitle:@"起止时间(单选)"
                                     iStarFilterItemType:ISTAR_FILTER_TYPE_SECTION_TITLE
                                     iStarFilterChooseType:ISTAR_CHOOSE_SINGLE
                                     iStarFilterGroup:ISTAR_GROUP_TIME];
    sectionTime.paramKey = @"btime";
    sectionTime.paramKey2 = @"etime";
    sectionTime.paramKey3 = @"define";
    __block IStarFilterModel *sectionTimeTmp = sectionTime;
    sectionTime.paramValue = ^id _Nonnull{
        for (IStarFilterModel * model in sectionTimeTmp.subArray) {
            if(model.select) {
                return model.firstBlock(); //开始时间
            }
        }
        return @"";
    };
    sectionTime.paramValue2 = ^id _Nonnull{
        for (IStarFilterModel * model in sectionTimeTmp.subArray) {
            if(model.select) {
                return model.secondBlock(); //结束时间
            }
        }
        return @"";
    };
    sectionTime.paramValue3 = ^id _Nonnull{
        for (IStarFilterModel * model in sectionTimeTmp.subArray) {
            if(model.select) {
                return [MSSxTool stringWithIStarFilterModel:model];
            }
        }
        return @"全部";
    };
    
    //全部 当天 24小时 3天 7天 自定义
    //---------------------------------------------
     IStarFilterModel *sectionTimeAll = [[IStarFilterModel alloc] initWithDisplayTitleTime:@"全部" iStarFilterType:ISTAR_FILTER_TYPE_ALL iStarTimeType:ISTAR_TIME_ALL];

    sectionTimeAll.firstBlock = ^id {
        //开始时间
        return @"";
    };
    sectionTimeAll.secondBlock = ^id {
        //结束时间
        return @"";
    };
    
    //---------------------------------------------
     IStarFilterModel *sectionTimeToday = [[IStarFilterModel alloc] initWithDisplayTitleTime:@"当天" iStarFilterType:ISTAR_FILTER_TYPE_SUB_TIME iStarTimeType:ISTAR_TIME_TODAY];
    //__block IStarFilterModel * sectionTimeTodaytmp = sectionTimeToday;
    sectionTimeToday.firstBlock = ^id _Nonnull{
        //开始时间
        return [NSString stringWithFormat:@"%@ 00:00", [IStarTimeUtils currentTimeStr:YYYYMMddSub]]; //当天
        
    };
    sectionTimeToday.secondBlock = ^id _Nonnull{
        //结束时间
        return [IStarTimeUtils currentTimeStr:yyyyMMddHHmmSub];
    };
    
    //---------------------------------------------
     IStarFilterModel *sectionTime24 = [[IStarFilterModel alloc] initWithDisplayTitleTime:@"24小时" iStarFilterType:ISTAR_FILTER_TYPE_SUB_TIME iStarTimeType:ISTAR_TIME_24];
    __block IStarFilterModel * sectionTime24tmp = sectionTime24;
    sectionTime24.firstBlock = ^id _Nonnull{
        //开始时间
        return [IStarTimeUtils beforeDay:1 now:sectionTime24tmp.secondBlock() format:yyyyMMddHHmmSub];
    };
    sectionTime24.secondBlock = ^id _Nonnull{
        //结束时间
        return [IStarTimeUtils currentTimeStr:yyyyMMddHHmmSub];
    };
    
    //---------------------------------------------
     IStarFilterModel *sectionTime3 = [[IStarFilterModel alloc] initWithDisplayTitleTime:@"3天" iStarFilterType:ISTAR_FILTER_TYPE_SUB_TIME iStarTimeType:ISTAR_TIME_3];
    sectionTime3.isdefault = YES;//时间的默认数据
    sectionTime3.select = YES;
    __block IStarFilterModel *sectionTime3tmp = sectionTime3;
    sectionTime3.firstBlock = ^id _Nonnull{
        return [IStarTimeUtils beforeDay:3 now:sectionTime3tmp.secondBlock() format:yyyyMMddHHmmSub];
        //开始时间
    };
    sectionTime3.secondBlock = ^id _Nonnull{
        //结束时间
        return [IStarTimeUtils currentTimeStr:yyyyMMddHHmmSub];
    };
    
    //---------------------------------------------
     IStarFilterModel *sectionTime7 = [[IStarFilterModel alloc] initWithDisplayTitleTime:@"7天" iStarFilterType:ISTAR_FILTER_TYPE_SUB_TIME iStarTimeType:ISTAR_TIME_7];
    __block IStarFilterModel *sectionTime7tmp = sectionTime7;
    sectionTime7.firstBlock = ^id _Nonnull{
        //开始时间
        return [IStarTimeUtils beforeDay:7 now:sectionTime7tmp.secondBlock() format:yyyyMMddHHmmSub];
    };
    sectionTime7.secondBlock = ^id _Nonnull{
        //结束时间
        return [IStarTimeUtils currentTimeStr:yyyyMMddHHmmSub];
    };
    
    //---------------------------------------------
    IStarFilterModel *sectionTimecutom = [[IStarFilterModel alloc] initWithDisplayTitleTime:@"自定义" iStarFilterType:ISTAR_FILTER_TYPE_SUB_CUSTOM_TIME_LONG  iStarTimeType:ISTAR_TIME_CUSTOM];
    __block IStarFilterModel *sectionTimecutomTmp = sectionTimecutom;
    sectionTimecutom.changeDisplayTitle = ^id _Nonnull{
        if(sectionTimecutomTmp.select) {
            return [NSString stringWithFormat:@"%@~%@", sectionTimecutomTmp.objStr1, sectionTimecutomTmp.objStr2];
        } else {
            return @"自定义";
        }
    };
    sectionTimecutom.firstBlock = ^id _Nonnull{
        //开始时间
        return [IStarTextTools avoidNilString:sectionTimecutomTmp.objStr1];
    };
    sectionTimecutom.secondBlock = ^id _Nonnull{
        //结束时间
        return [IStarTextTools avoidNilString:sectionTimecutomTmp.objStr2];
    };
    
    [sectionTime addSubArrayModel: sectionTimeAll];
    [sectionTime addSubArrayModel: sectionTimeToday];
    [sectionTime addSubArrayModel: sectionTime24];
    [sectionTime addSubArrayModel: sectionTime3];
    [sectionTime addSubArrayModel: sectionTime7];
    [sectionTime addSubArrayModel: sectionTimecutom];
    return sectionTime;
}

显示根据类型进行区分

获取标题宽度等

// 获取标题宽度等
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
    IStarFilterModel *sectionModel = [self.iStarFilterModel modelAtSubArrayIndex:section];
    if(sectionModel.iStarFilterItemType == ISTAR_FILTER_TYPE_LINE_LONG) {
        return CGSizeMake([UIScreen mainScreen].bounds.size.width - 50, 0.3);
    } else {
        return CGSizeMake([UIScreen mainScreen].bounds.size.width - 50, 18);
    }
}

得到可用的Cell显示数据

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView
           viewForSupplementaryElementOfKind:(NSString *)kind
                                 atIndexPath:(NSIndexPath *)indexPath {
    if ([kind isEqual:UICollectionElementKindSectionHeader]) {
        IStarFilterModel *sectionModel = [self.iStarFilterModel modelAtSubArrayIndex:indexPath.section];
        if(sectionModel.iStarFilterItemType == ISTAR_FILTER_TYPE_LINE_LONG) {
            UICollectionReusableView *headeview=[collectionView dequeueReusableSupplementaryViewOfKind:kind withReuseIdentifier:sectionLineCellID forIndexPath:indexPath];
            headeview.backgroundColor= ISTAR_COLOR_E6E6E6;//[UIColor yellowColor];
            return headeview;
        } else if(sectionModel.iStarFilterItemType == ISTAR_FILTER_TYPE_SECTION_TITLE_BIG) {
            IStarFilterHeader *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:sectionBigTitleCellId forIndexPath:indexPath];

            //view.imageView.image = [UIImage imageNamed:@"btn_more"];
            view.labelTitle.font = SYSTEM_FONT_PFSM(12);
            view.labelTitle.textColor = RGBAllColor(0x333333);
            view.labelTitle.text = [self.iStarFilterModel modelAtSubArrayIndex:indexPath.section].displayTitle;
            return view;
        } else {
            IStarFilterHeader *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:sectionCellID forIndexPath:indexPath];
            
            //view.imageView.image = [UIImage imageNamed:@"btn_more"];
            view.labelTitle.textColor = RGBAllColor(0x666666);
            view.labelTitle.font = SYSTEM_FONT_PFS(12);
            view.labelTitle.text = [self.iStarFilterModel modelAtSubArrayIndex:indexPath.section].displayTitle;
            return view;
        }
        
    }
    return nil;
}

点击的时候判断单选还是多选

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    
    //[MSSxTool getAllCustomConditionSx]; //测试用
    
    IStarFilterModel *sectionModel = [self.iStarFilterModel modelAtSubArrayIndex:indexPath.section];
    IStarFilterModel *model = [sectionModel modelAtSubArrayIndex:indexPath.row];
    //找出自定义时间
    if(sectionModel.iStarFilterGroup == ISTAR_GROUP_TIME
       && model.iStarFilterItemType == ISTAR_FILTER_TYPE_SUB_CUSTOM_TIME_LONG) {
        //自定义时间, 因为时间是单选,不用排除
        [self clickCustomTimeCollectionView:collectionView withIndex:indexPath];
    } else if(sectionModel.iStarFilterChooseType == ISTAR_CHOOSE_MULTI) {//区分单选多选
        //多选
        [self clickMultiWithCollectionView:collectionView withIndex:indexPath];
    } else if(sectionModel.iStarFilterChooseType == ISTAR_CHOOSE_SINGLE) {
        //单选
        [self clickSingleWithCollectionView:collectionView withIndex:indexPath];
    }
}

单选

// 单选
-(void)clickSingleWithCollectionView:(UICollectionView*)collectionView withIndex:(NSIndexPath*)indexPath{
    // 取消所有的选中,然后再选中那一个
    IStarFilterModel *sectionModel = [self.iStarFilterModel modelAtSubArrayIndex:indexPath.section];
    [sectionModel.subArray enumerateObjectsUsingBlock:^(IStarFilterModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        obj.select = NO;
    }];
    [sectionModel modelAtSubArrayIndex:indexPath.row].select = YES;
    [UIView performWithoutAnimation:^{
        [self.homeView reloadSections:[[NSIndexSet alloc]initWithIndex:indexPath.section]];
    }];
}

多选

// 多选
-(void)clickMultiWithCollectionView:(UICollectionView*)collectionView withIndex:(NSIndexPath*)indexPath{
    //至少选择一个
    IStarFilterModel *sectionModel = [self.iStarFilterModel modelAtSubArrayIndex:indexPath.section];
   
    IStarFilterModel *subModel = [sectionModel modelAtSubArrayIndex:indexPath.row];
    
    if(subModel.iStarFilterItemType == ISTAR_FILTER_TYPE_ALL) {//点击全部的时候,其他的要取消
        [sectionModel.subArray enumerateObjectsUsingBlock:^(IStarFilterModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            obj.select = NO;
        }];
        subModel.select = YES;
    } else {
        if(subModel.select) {
            // 取消之前判断是否只剩一个,剩一个就不变
            NSInteger count=0;
            for (IStarFilterModel *model in sectionModel.subArray) {
                if(model.iStarFilterItemType == ISTAR_FILTER_TYPE_ALL) {
                    model.select = NO;
                } else {
                    if(model.select) {
                        count+=1;
                    }
                }
            }
            if(count > 1) {
                [sectionModel modelAtSubArrayIndex:indexPath.row].select = NO;
            }
        } else {
            subModel.select = YES;
            BOOL isAllSelect = YES;
            for (IStarFilterModel *model in sectionModel.subArray) {
                if(model.iStarFilterItemType != ISTAR_FILTER_TYPE_ALL) {
                    if(!model.select) {
                        isAllSelect = NO; //有没选中的数据
                    }
                } else {
                    model.select = NO;//全选去掉
                }
            }
            if(isAllSelect) { //其他所有的选中
                [sectionModel.subArray enumerateObjectsUsingBlock:^(IStarFilterModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                    if(obj.iStarFilterItemType == ISTAR_FILTER_TYPE_ALL) {
                        obj.select = YES;
                    } else {
                        obj.select = NO;
                    }
                }];
            }
        }
    }

    [UIView performWithoutAnimation:^{
        [self.homeView reloadSections:[[NSIndexSet alloc]initWithIndex:indexPath.section]];
    }];
}

时间是区分于其他的

-(void)clickCustomTimeCollectionView:(UICollectionView*)collectionView withIndex:(NSIndexPath*)indexPath{
    
    NSString *beginTime = [IStarTimeUtils currentTimeStr:yyyyMMddHHmmSub];
    NSString *endTime = [IStarTimeUtils currentTimeStr:yyyyMMddHHmmSub];
    
    __weak typeof(self) weakSelf = self;
    IStarDefineTimeView *view = [[IStarDefineTimeView alloc] initWithBegin:beginTime endTime:endTime];
    view.definetime = ^(NSString * _Nonnull beginTime, NSString * _Nonnull endTime) {
        NSLog(@"%@", beginTime);
        NSLog(@"%@", endTime);
        
        if([IStarTimeUtils judgeBigBegin:beginTime endTime:endTime format:yyyyMMddHHmmSub]){
            [MSMBProgressHUD showError:@"开始时间不能大于结束时间" toView:weakSelf.view];
            return ;
        }
        
        IStarFilterModel *sectionModel = [weakSelf.iStarFilterModel modelAtSubArrayIndex:indexPath.section];
        IStarFilterModel *model = [sectionModel modelAtSubArrayIndex:indexPath.row];
        model.objStr1 = beginTime;
        model.objStr2 = endTime;
        [self clickSingleWithCollectionView:collectionView withIndex:indexPath];
        [UIView performWithoutAnimation:^{
            [weakSelf.homeView reloadSections:[[NSIndexSet alloc]initWithIndex:indexPath.section]];
        }];
    };
    [view show];
}