下拉框筛选控件

作者: 爆炸头的波波安 | 来源:发表于2016-12-23 17:03 被阅读2901次
    封面.jpg

    Demo效果:

    example.gif

    工程结构图:

    结构图.png
    1.模拟组装数据,因为可能是多层的,所以我们这里通过组合模式来组装数据。在MMBaseItem里面我们定义了三个枚举:
    //这个字段我们暂时留着以后扩展,覆盖可能要有些选项不能选择,显示灰色的情况
    typedef NS_ENUM(NSUInteger, MMPopupViewMarkType) {  //选中的状态
        MMPopupViewDisplayTypeSelected = 0,      //可以选中
        MMPopupViewDisplayTypeUnselected = 1,    //不可以选中
    };
    
    typedef NS_ENUM(NSUInteger, MMPopupViewSelectedType) {     //是否支持单选或者多选
        MMPopupViewSingleSelection,                            //单选
        MMPopupViewMultilSeMultiSelection,                    //多选
    };
    
    typedef NS_ENUM(NSUInteger, MMPopupViewDisplayType) {  //分辨弹出来的view类型
        MMPopupViewDisplayTypeNormal = 0,                //一层
        MMPopupViewDisplayTypeMultilayer = 1,            //两层
        MMPopupViewDisplayTypeFilters = 2,               //混合
    };
    

    MMItem提供共同的接口,弹出视图由对应的MMItem子类数据驱动。 由于MMPopupViewDisplayTypeNormalMMPopupViewDisplayTypeMultilayer两种类型布局比较单一简单,所以layout对象暂时只是在MMPopupViewDisplayTypeFilters时有用。

    当然我这里是模拟数据。下面给出一种建立树模型的思路:

    屏幕快照 2016-12-22 下午11.14.13.png
    1.1 首先我们把上图的根节点放到队列中
    1.1.png
    1.2 根据A持有子节点的指针把B,C放进队列,相当于把B,C添加到A的childrenNodes。然后把A给移出队列。
    1.2
    1.3 然后按照上面的逻辑一个一个的遍历每个节点。直到队列为空的时候代表一颗建立完毕。下面图未给全,只是部分状态的时刻图。 1.3.png 1.4.png
    1.5.png

    2.初始化视图:

     MMComBoBoxView *view = [[MMComBoBoxView alloc] initWithFrame:CGRectMake(0, 64, kScreenWidth, 40)];
        view.dataSource = self;
        view.delegate = self;
        [self.view addSubview:view];
        [view reload];
    

    3.通过datasource协议将数据传给MMComBoBoxView,你可以联想UITableView数据驱动方式就可以了。

    #pragma mark - MMComBoBoxViewDataSource
    - (NSUInteger)numberOfColumnsIncomBoBoxView :(MMComBoBoxView *)comBoBoxView {
        return self.mutableArray.count;
    }
    - (MMItem *)comBoBoxView:(MMComBoBoxView *)comBoBoxView infomationForColumn:(NSUInteger)column {
        return self.mutableArray[column];
    }
    

    4.我们会通过MMComBoBoxViewDelegate协议把选中的路径回调出来,这里我们选择回调存储路径的数组的本质是在于可能开发人员上传的不止是title,可能还有对应的code等一系列的字段。这样方便扩展。

    #pragma mark - MMComBoBoxViewDelegate
    - (void)comBoBoxView:(MMComBoBoxView *)comBoBoxViewd didSelectedItemsPackagingInArray:(NSArray *)array atIndex:(NSUInteger)index {
        MMItem *rootItem = self.mutableArray[index];
        switch (rootItem.displayType) {
            case MMPopupViewDisplayTypeNormal:
            case MMPopupViewDisplayTypeMultilayer:{
                //拼接选择项
                NSMutableString *title = [NSMutableString string];
                __block NSInteger firstPath;
                [array enumerateObjectsUsingBlock:^(MMSelectedPath * path, NSUInteger idx, BOOL * _Nonnull stop) {
                    [title appendString:idx?[NSString stringWithFormat:@";%@",[rootItem findTitleBySelectedPath:path]]:[rootItem findTitleBySelectedPath:path]];
                    if (idx == 0) {
                    firstPath = path.firstPath;
                  }
                }];
                NSLog(@"当title为%@时,所选字段为 %@",rootItem.title ,title);
                break;}
            case MMPopupViewDisplayTypeFilters:{
               MMCombinationItem * combineItem = (MMCombinationItem *)rootItem;
                [array enumerateObjectsUsingBlock:^(NSMutableArray*  _Nonnull subArray, NSUInteger idx, BOOL * _Nonnull stop) {
                    if (combineItem.isHasSwitch && idx == 0) {
                        for (MMSelectedPath *path in subArray) {
                         MMAlternativeItem *alternativeItem = combineItem.alternativeArray[path.firstPath];
                          NSLog(@"当title为: %@ 时,选中状态为: %d",alternativeItem.title,alternativeItem.isSelected);
                        }
                        return;
                    }
                    
                    NSString *title;
                    NSMutableString *subtitles = [NSMutableString string];
                    for (MMSelectedPath *path in subArray) {
                        MMItem *firstItem = combineItem.childrenNodes[path.firstPath];
                        MMItem *secondItem = combineItem.childrenNodes[path.firstPath].childrenNodes[path.secondPath];
                        title = firstItem.title;
                        [subtitles appendString:[NSString stringWithFormat:@"  %@",secondItem.title]];
                    }
                      NSLog(@"当title为%@时,所选字段为 %@",title,subtitles);
                }];
    
                break;}
            default:
                break;
        }
    }
    

    如果你觉得这篇文章对你有所帮助,欢迎like或star!谢谢!
    demo地址

    相关文章

      网友评论

      • 爱敲代码的果果:请教,这个筛选 添加在tableview section header中,会导致下拉菜单位置不对,怎么去相对定位 ?在线急等
      • MJ_XU:楼主,请教,这个筛选 添加在tableview section header中,会导致下拉菜单位置不对,怎么去相对定位 ? 我看来代码 发现 筛选的位置 是通过 box的高度与 y 来决定的。
      • 6a886a41feff:您好,问一下,那个二级联动,我可以在第二级进行自定义视图吗?
      • BlueFriends:刚进来默认某一个颜色是选中怎么弄
      • 淰戀:哥哥!~~你哪时候上线啊!!我也想知道默认选中的那一行如何能点击。。。美团那边可以点击额。。
      • JVSFlipped:刚刚写完一个差不多的 用了两天半:pensive::pensive::pensive::pensive:应该早点关注你的:pensive::pensive::pensive::pensive:
      • 16b94580df5e:如果我要取左侧table的数据,但是还要判断是第几列的table如何判断呢
      • pluskok:这个控件初始化后 ,后续还能不能改变最上面标题选项的个数了?急求
        pluskok:@爆炸头的波波安 到底行不行啊,刚才 github上你咋说有思路 那个可行吗
        pluskok:@爆炸头的波波安 好吧
        爆炸头的波波安:@爱上雨天的鱼 暂时不能
      • iOS游学者:筛选那块能同时有多选和单选吗?
      • Raindew:对于,如果我需要混合型,又不需要你上面定义的UISwitch,我希望混合可以自己定义视图,这样如何做呢
        爆炸头的波波安:@Raindew ,大兄弟,不会有打扰之说的,我简信你了。
        Raindew:@theway 可以留个QQ么,如果有问题方便请教,不会很打扰你的。
        爆炸头的波波安:@Raindew 弹出的混合视图持有一个UITableView,根据你传过来MMItem数据来做驱动。你可以自己去自定义头视图和单元格。
      • aa5b822cf9eb:受教了:stuck_out_tongue_winking_eye:
      • leftwater:不错
      • 昵称经已被占用::+1::+1:🏻:+1:🏼:+1:🏽:+1:🏾:+1:🏿

      本文标题:下拉框筛选控件

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