(iOS)商城筛选

作者: RocketsChen | 来源:发表于2017-08-20 15:14 被阅读4353次

    商城筛选的功能的Demo,实现如下功能:【CollectionView】初步展示数据,Section展开/折叠,以及用户选择。

    先展示几张Demo界面图
    Demo初始界面值 点击选择

    分析实现步骤

    1.数据
    手动创建一个FiltrateItem.plist,如下图展示数据模型结构
    plist
    2.懒加载初始化CollectionView,字典转模型,设置数据源
    - (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数据
    - (void)setUpFiltrateData
    {
        _filtrateItem = [DCFiltrateItem mj_objectArrayWithFilename:@"FiltrateItem.plist"];
    }
    
    #pragma mark - <UICollectionViewDelegate>
    - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
        //这里默认第一组品牌展示两行数据其余展示一行数据(3个一行)
        return (_filtrateItem[section].isOpen == YES) ? self.filtrateItem[section].content.count : (section == 0) ? 6 : 3 ;
    }
    
    

    Demo中筛选控制的宽度我定义宏为窗口的宽度*0.8 ,每个Item的宽度为(FiltrateViewScreenW - 6 * 5) / 3,已经手动算上间距 如下图

    间距图
    #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中创建一个按钮,按钮contentButton尺寸为DCAttributeItemCell的尺寸,根据模型数据的isSelect数据,改变字体,背景颜色等设置,注意一定记得要把按钮的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.根据模型获取每组选择的数据和最后总获得数据

    点击事件,通过模型讲已选的属性加入数组中,这个主意我初始化的数组内部还嵌套了多个数组层次结构类似:@[@[],@[],@[]],这样我们根据内部数组的值来给每个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;
        
        //数组mutableCopy初始化,for循环加数组 结构大致:@[@[],@[]] 如此
        _seleArray = [@[] mutableCopy];
        for (NSInteger i = 0; i < _filtrateItem.count; i++) {
            NSMutableArray *section = [@[] mutableCopy];
            [_seleArray addObject:section];
        }
        
        //把所选的每组Item分别加入每组的数组中
        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);
                }
            }
    
        }
    }
    
    这样我们商品的筛选就简单的实现了,下面附上一个演示GIF
    演示GIF

    总结:Demo只是初步展示除电商类APP的筛选功能的思路,近期我将完善下,更新到我的开源电商CDDMall项目上,有需要的可以去GitHub上下载~

    相关文章

      网友评论

      • TryToFlyHigher:这个demo能发给我一份吗 15840995068@163.com THX:blush:
      • 蜡笔小新Zzz:你好,楼主!能麻烦你单独发你这个的demo吗?想参考一下,有类似的功能
      • COREwWw:楼主你好,我遇到clang: error: linker command failed with exit code 1 (use -v to see invocation)
        这个错误怎么解决啊?
        RocketsChen:@COREwWw 打开终端 , cd 我的项目 return , pod update
        COREwWw:@RocketsChen 不太会:sweat::sweat:
        RocketsChen:@COREwWw 你更新下静态库试试
      • PGOne爱吃饺子:楼主 你好有没有单独的这一个demo 谢谢
        PGOne爱吃饺子:@RocketsChen 我就想看一下你的思路
        PGOne爱吃饺子:@RocketsChen 可以发给我一下么
        RocketsChen:@4140d18ee6fc 有的,demo只是展示实现思路

      本文标题:(iOS)商城筛选

      本文链接:https://www.haomeiwen.com/subject/aksfdxtx.html